Desen

2011-07-08 35 views
26

Desen

public interface IPagedList<T> 
{ 
    IEnumerable<T> PageResults { get; } 
    int CurrentPageIndex { get; } 
    int TotalRecordCount { get; } 
    int TotalPageCount { get; }   
    int PageSize { get; } 
} 

Şimdi çağrı kontrolü olan bir çağrı kontrolünü

public class PagedListPager<T> 
{ 
    public PagedListPager<T>(IPagedList<T> list) 
    { 
     _list = list; 
    } 

    public void RenderPager() 
    { 
     for (int i = 1; i < list.TotalPageCount; i++) 
      RenderLink(i); 
    } 
} 

oluşturmak istiyorum ben sayfalamalı liste sergilemek için aşağıdaki arayüze sahip Say T numaralı telefona ilgi gösterilmiyor (listenin gerçek içeriği). Sadece sayfa sayısı, geçerli sayfa vb. Gerektirir. Yani PagedListPager'un tek nedeni jeneriktir, böylece jenerik IPagedList<T> paramater ile derlenecektir.

Bu bir kod kokusu mu? Olumlu bir genel olarak etkili olduğumu umursamıyorum?

Arabirimin genel olmayan bir sürümünü açığa çıkarmak için böyle bir durumda standart bir desen var mı, bu nedenle, genel tipini çağrı cihazında kaldırabilirim?

public class PagedListPager(IPagedList list) 

Düzenleme ben de bu sorunu çözdük akım yolu ekleyebilir ve uygun bir çözüm olmadığı konusunda bir yorum davet düşündüm

:

public interface IPagedList // non-generic version 
{ 
    IEnumerable<object> PageResults { get; } 
    int CurrentPageIndex { get; } 
    int TotalRecordCount { get; } 
    int TotalPageCount { get; }   
    int PageSize { get; } 
} 


public class ConcretePagedList<T> : IPagedList<T>, IPagedList 
{ 
    #region IPagedList<T> Members 

    public IEnumerable<T> PageResults { get; set; } 
    public int CurrentPageIndex { get; set; } 
    public int TotalRecordCount { get; set; } 
    public int PageSize { get; set; } 

    #endregion 

    #region IPagedList Members 

    IEnumerable<object> IPagedList.PageResults 
    { 
     get { return PageResults.Cast<object>(); } 
    } 

    #endregion 
} 

Şimdi, genel olmayan sınıflara/işlevlere geçebilirim

+0

PagedListPager 'bir sınıf veya yöntem beyanı mıdır? –

+0

@Gregg oops üzgünüm bunu değiştireceğim. – fearofawhackplanet

+0

Farklı arabirimler yapmak için bunları açıkça uygulayabileceğiniz gibi, her iki arabirimde de tanımlanmış özellikleri kullanmaktan hoşlanmıyorum. Örneğin, IPagedList.PageSize {get {return 8;}} IPageList .PageSize {get {return this.PageResults.Count();}} İkinci arayüze sahip olmanızın tek sebebi güçlü yazım sağlamaktır, bu yüzden Marc'ın cevabı, sınıfın farklı olmaması gereken özellikler üzerinde farklı sonuçlar elde etme yeteneğini ortadan kaldırıyor gibi görünmektedir. – MPavlak

cevap

27

Benim yaklaşımımyeniden bildirmek için new kullanmak ve :

public interface IPagedList 
{ 
    int CurrentPageIndex { get; } 
    int TotalRecordCount { get; } 
    int TotalPageCount { get; }   
    int PageSize { get; } 

    Type ElementType { get; } 
    IEnumerable PageResults { get; } 
} 

public interface IPagedList<T> : IPagedList 
{ 
    new IEnumerable<T> PageResults { get; } 
} 

Bu irade, ancak, "açık arabirim uygulaması" gerektirir yani

class Foo : IPagedList<Bar> 
{ 
    /* skipped : IPagedList<Bar> implementation */ 

    IEnumerable IPagedList.PageResults { 
     get { return this.PageResults; } // re-use generic version 
    } 
    Type IPagedList.ElementType { 
     get { return typeof(Bar); } 
    } 
} 

Bu yaklaşım jenerik ve genel olmayan API hem yoluyla tamamen kullanılabilir API yapar.

+0

Teşekkürler Marc, bunun neye benzediğime oldukça benzer ama biraz daha nezih bir uygulama ile. – fearofawhackplanet

+0

Mükemmel - basit, temiz ve okunması kolay. – Chris

+1

Bu, Özellikler'in aksine Yöntemlerle nasıl çalışır? – Moop

4

public interface IPageSpecification 
    { 
     int CurrentPageIndex { get; } 
     int TotalRecordCount { get; } 
     int TotalPageCount { get; }   
     int PageSize { get; } 
    } 

public interface IPagedList<T> : IPageSpecification 
{ 
    IEnumerable<T> PageResults { get; } 
} 

ilk iki arayüzleri, gördüğünüz gibi, IPagedList IPageSpecification türetilmiştir tanımlayın. Metodunuzda sadece IPageSpecification parametresini kullanın. Diğer durumlarda, IPagedList - IPagedList uygulayıcıları da

7

Seçeneklerden biri 2 arayüzleri yaratmaktır IPageSpecification verileri içerecektir şekilde: o zaman

public interface IPagedListDetails 
    { 
     int CurrentPageIndex { get; } 
     int TotalRecordCount { get; } 
     int TotalPageCount { get; } 
     int PageSize { get; } 
    } 

    public interface IPagedList<T> : IPagedListDetails 
    { 
     IEnumerable<T> PageResults { get; } 
    } 

Ve kontrolü:

public class PagedListPager(IPagedListDetails details) 
+0

Bunu düşünmüştüm ama arayüz kalıtımının genel olarak iyi bir fikir olarak görülmediği izlenimiydi? – fearofawhackplanet

+0

Arabirim kalıtımında bir sorun yok, .NET BCL'nin etrafına bakacak olursanız, jenerik olmayan sınıflardan miras alan çeşitli genel arabirimler olduğunu göreceksiniz – Ankur

+1

@fearofawhackplanet: IMHO arabirimi mirası çok az kullanılıyor. IMHO, IList gibi bir şey, IReadableByIndex, IMutableByIndex, IAppendable ve IRemovableByIndex; diziler ilk ikisini uygulamış olmalı, ancak son ikisini değil. – supercat