I started this extension method for fun, but now I find myself stuck into it,
I started this extension method for fun, but now I find myself stuck into it,
Actually I want to create an extension method to extend LINQ, the method will look like this:
books.In(b => b.Id, 1,2,3,4,5);
It will return books with Id range in the second params[]
,
It also could be done like this:
books.In(b => b.Title, "t1","t2","t3","t4","t5");
What I come up with is this method (I just knew about expression tree today!):
public static List<TEntity> In<TEntity, TMember>(this List<TEntity> list,
Expression<Func<TEntity, TMember>> identifier, params TMember[] keys)
{
Type t = typeof(TEntity); //How to use reflection here?
List<TEntity> myList = list.Where(m => keys.Contains(m.));
return myList;
}
my problem is how to access the generic class members: i.e. m.Id
or m.Title
from the identifier
expression? Can I use reflection to make this happen?
--------------------------------------------------------------------------------------------------------------------------
Best Answer;
This should do:
public static IEnumerable<TEnitity> In<TEnitity, TMember>(this IEnumerable<TEnitity> source, Func<TEnitity, TMember> projector, IEnumerable<TMember> validCases) =>
source.Where(s => validCases.Contains(projector(s)));
Or, to comply exaclty with the signature you are proposing:
public static IEnumerable<TEntity> In<TEntity, TMember>(this IEnumerable<TEntity> source, Func<TEntity, TMember> projector, params TMember[] validCases) =>
source.Where(s => validCases.Contains(projector(s)))
On why I'm returning IEnumerable<T>
instead of List<T>
the reasoning is cheap generalization; if the consumer wants a list returned, then he simply needs to call ToList
, but why make him pay the expense of enumerating greedily if maybe he only wants to iterate once through the enumeration? Remeber, LINQ is lazy, leverage that and make it work as little as possible.
On why I'm accepting IEnumerable<T>
as an argument, again cheap generalization; why accept only a list? Why not an array, a queue, a stack, a collection, an iterator block, a hashset, etc?