簡體   English   中英

暴露非泛型版本的泛型接口的模式

[英]Pattern for exposing non-generic version of generic interface

假設我有以下用於公開分頁列表的界面

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>傳遞給非泛型類/函數

我的方法是使用new重新聲明PageResults ,並將T公開為Type

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 完全可用。

一種選擇是創建 2 個接口,例如:

    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)

定義兩個接口,首先

    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 作為參數。 在其他情況下,IPagedList - IPagedList 的實現者也將包含來自 IPageSpecification 的數據

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM