2011-07-08 9 views
26

パターンは

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

は、今私は、ページングコントロールが持つページング制御

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); 
    } 
} 

を作成したい、私はページングリストを露出させるため、以下のインタフェースを持っていると言いますT(リストの実際の内容)には関心がありません。ページ数、現在のページ数などが必要です。PagedListPagerの一般的な理由は、IPagedList<T>パラメータでコンパイルするためです。

これはコードのにおいですか?私は実質的に冗長なジェネリックを持つことに気を付けるべきですか?

このような場合、インターフェイスの非汎用バージョンを公開するための標準パターンはありますか?そのため、ページャでジェネリックタイプを削除できますか?

public class PagedListPager(IPagedList list) 

編集私はまた、私はこの問題を解決してきた現在の方法を追加し、それが適切な解決策だかどうかについてコメントを招待しようと思いました

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 
} 

今では、非汎用クラス/関数にConcretePagedList<T>を渡すことができます

+0

'PagedListPager 'はクラス宣言またはメソッド宣言ですか? –

+0

@Greggよ、申し訳ありません、私はそれを編集します。 – fearofawhackplanet

+0

私は両方のインターフェイスで定義されたプロパティを持っているのが好きではありません。たとえば、IPagedList.PageSize {get {return 8;}} IPageList .PageSize {get {return this.PageResults。あなたが2番目のインターフェイスを持つ唯一の理由は、厳密な型定義を提供することです。そのため、Marcの答えは、クラスが異なるプロパティで異なる結果を持つ能力を削除するようです。 – MPavlak

答えて

27

私のアプローチ - 他の例では、IPagedList IPagedListの実装は一つのオプションは、その2つのインターフェイスを作成することですIPageSpecification

+0

ありがとうMarc、私はこれが好きですが、これは私が思いついたものと非常によく似ていますが、やや良い実装です。 – fearofawhackplanet

+0

優秀 - シンプルで清潔で読みやすい。 – Chris

+1

プロパティとは対照的に、メソッドとはどのように動作しますか? – 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; } 
} 

最初の二つのインターフェース、ご覧のとおり、IPagedListがIPageSpecificationから派生さを定義します。あなたのメソッドでは、パラメータとしてIPageSpecificationだけを使用してください。

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

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

そしてあなたのコントロール:

public class PagedListPager(IPagedListDetails details) 
7

からのデータをも含んでいるでしょうここでnewを使用してPageResultsを再宣言し、TTypeとして公開します。

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; } 
} 

これは、しかし、すなわち

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); } 
    } 
} 

を「明示的なインターフェイスの実装」を必要とするこのアプローチは、両方の一般的および非汎用APIを介して、APIが完全に使用可能となります。

+0

私はこれを考えていましたが、インターフェイスの継承は一般的には良い考えではないという印象を受けましたか? – fearofawhackplanet

+0

.NET BCLを見渡すと、インタフェース継承に問題はありません。非汎用クラスから継承するさまざまな汎用インタフェースがあることがわかります。 – Ankur

+1

@fearofawhackplanet:IMHOインタフェースの継承が大幅に活用されていません。 IMHO、IListはIReadableByIndex、IMutableByIndex、IAppendable、IRemovableByIndexから派生している必要があります。配列は最初の2つを実装していて、最後の2つを実装していないはずです。 – supercat