Создание общего метода расширения для обеспечения функциональности фильтрации - PullRequest
3 голосов
/ 13 февраля 2012

Я работаю над методом расширения, чтобы обеспечить возможности фильтрации для нескольких объектов. Участвующие сущности бывают разных типов, но имеют общие поля, по которым можно искать.

Ниже работает в данный момент, однако мне было интересно, можно ли это "обобщить", чтобы не происходило приведение от обобщенного к явному типу?

public static IQueryable<T> PriceLow<T>(this IQueryable<T> query, decimal? priceLow)
{
    if (typeof(T) == typeof(Entity1))
    {
        var innerQuery = (IQueryable<Entity1>) query;
        var results = priceLow.HasValue ? innerQuery.Where(o => (o.ListPrice > priceLow.Value)) : innerQuery;
        return (IQueryable<T>) results;
    }

    if (typeof(T) == typeof(Entity2))
    {
        var innerQuery = (IQueryable<Entity2>)query;
        var results = priceLow.HasValue ? innerQuery.Where(o => (o.ListPrice > priceLow.Value)) : innerQuery;
        return (IQueryable<T>)results;
    }

    return null;
}

Пример использования:

    var foo = _repository.GetAllEntity1().PriceLow(_searchCritera.PriceLow);

Ответы [ 3 ]

3 голосов
/ 13 февраля 2012

Если вы можете изменить два типа сущностей для реализации общего интерфейса, который имеет общие свойства / методы, тогда вы можете использовать ограничение общего типа. Это также будет работать с общим базовым классом.

Сделайте это, и тогда ваша подпись будет выглядеть так (подробности беспорядка опущены):

public static IQueryable<T> PriceLow<T>(...)
  where T : ICommonInterface
2 голосов
/ 13 февраля 2012

Как насчет того, чтобы заставить ваши объекты наследовать от базового типа, который содержит поля для поискаТаким образом, ваш метод фильтра должен знать только об одном базовом типе.

1 голос
/ 13 февраля 2012

Один из подходов состоит в том, чтобы определить интерфейс и добавить этот интерфейс как одну из вещей, наследуемых вашим классом. Интерфейс не должен содержать ничего вообще. Его можно просто использовать как маркер.

Тогда сделайте так, чтобы ваш метод расширения требовал аргумент, что интерфейс.

...