Подтвердить что ты не робот

Шаблон для публикации не общей версии общего интерфейса

Скажем, у меня есть следующий интерфейс для отображения выгружаемого списка

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)

Edit

Я думал, что добавлю и нынешний способ, я решил эту проблему и предложил комментарии о том, подходит ли это решение:

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> в не общие классы/функции

4b9b3361

Ответ 1

Мой подход здесь состоял в том, чтобы использовать 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)

Ответ 3

Определите два интерфейса: сначала

    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