2015-02-14 6 views
-2

У меня есть этот метод, который я хочу написать:Как написать метод расширения linq для всех типов?

public static IQueryable<TSource> CutTo<TSource>(this IQueryable<TSource> source, Func<int> func) 
{ 
    int index = func(); 
    // here I can write something for all types or switch all 
    // the types and write code for every type 
} 

Что это самый простой способ, чтобы закодировать это для всех типов TSource?

Редактировать: Black Bear пишет, что это уже работает для всех типов, но это не так. Mono пишет так:

public static IQueryable<TSource> Where<TSource> (this IQueryable<TSource> source, Expression<Func<TSource, bool>> predicate) 
{ 
    Check.SourceAndPredicate (source, predicate); 

    return source.Provider.CreateQuery<TSource> (
     StaticCall (
      MakeGeneric (MethodBase.GetCurrentMethod(), typeof (TSource)), 
      source.Expression, 
      Expression.Quote (predicate))); 
} 
+0

Это уже работает для всех типов – BlackBear

+2

Что должно делать CutTo, и каково значение func и его возвращаемого значения? – Dirk

ответ

1

Первое решение (уборщик один)

будет работать только с типами, которые реализуют определенный интерфейс

Создать интерфейс IHaveId

public interface IHaveId 
{ 
    int Id { get; set; } 
} 

Тогда каждая модель с Id должным образом реализовать IHaveId. Пример

public class Post : IHaveId 
{ 
    int Id { get; set; } 
    string Title { get; set; } 
    string Content { get; set; } 
} 

А затем написать свой метод CutTo как:

public static IQueryable<T> CutTo<T>(this IQueryable<T> source, Func<int> func) 
    where T: IHaveId 
{ 
    int index = func(); 
    return source.Where(x => x.Id == index); 
} 

Идея заключается в том, что каждая реализация IHaveId будет иметь int свойство Id, а затем вы можете ограничить CutTo метод работать только с реализациями IHaveId и используйте их Id.

Второе решение (уродливее)

будет работать с любым типом, который держит Entity Framework соглашение об именах первичных ключей

  1. Используйте отражение над typeof(TSource), чтобы найти свойство с именем Id или typeof(TSource).Name + "Id"
  2. Опять с рефлекторной сборкой Expression<Func<TSource, int>> и примените ее в IQueryable<T> source с предложением Where.
+0

Я хочу, чтобы каждый доступный тип был включен. –

+0

Я отредактировал свой ответ со вторым решением, которое является более общим, но уродливым. –