我开始使用这种扩展方法很有趣,但现在我发现自己陷入其中,
实际上我想创建一个扩展方法来扩展LINQ,方法将如下所示:
books.In(b => b.Id, 1,2,3,4,5);
它会在第二个params[]
,
也可以这样做:
books.In(b => b.Title, "t1","t2","t3","t4","t5");
我想出的是这种方法(我今天才知道表达式树!):
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;
}
我的问题是如何访问通用类成员:m.Id
表达式m.Title
或identifier
?
我可以使用反射来实现这一目标吗?
答案 0 :(得分:2)
这应该做:
public static IEnumerable<TEnitity> In<TEnitity, TMember>(
this IEnumerable<TEnitity> source,
Func<TEnitity, TMember> projector, IEnumerable<TMember> validCases)
{
var validSet = new HashSet<TMember>(validCases);
return source.Where(s => validSet.Contains(projector(s)));
}
或者,为了遵守您提出的签名:
public static IEnumerable<TEntity> In<TEntity, TMember>(
this IEnumerable<TEntity> source,
Func<TEntity, TMember> projector, params TMember[] validCases)
{
var validSet = new HashSet<TMember>(validCases);
return source.Where(s => validSet.Contains(projector(s)));
}
关于我为什么要返回IEnumerable<T>
而不是List<T>
,推理是廉价的推广;如果消费者想要返回一个列表,那么他只需要调用ToList
,但为什么让他付出贪婪地枚举的费用,如果他只想在枚举中迭代一次?记住,LINQ是 lazy ,利用它并尽可能少地工作。
为什么我接受IEnumerable<T>
作为论据,又是廉价的概括;为什么只接受清单?为什么不是数组,队列,堆栈,集合,迭代器块,哈希集等?