天天看点

Linq的Distinct太不给力了

假设我们有一个类:Product

Main函数如下:

可以看到distinctProduct 的结果是:

<a href="http://images.cnblogs.com/cnblogs_com/LoveJenny/201108/201108011958493810.png"></a>

因为Distinct 默认比较的是Product对象的引用,所以返回4条数据。

那么如果我们希望返回Id唯一的product,那么该如何做呢?

Distinct方法还有另一个重载:

该重载接收一个IEqualityComparer的参数。

假设要按Id来筛选,那么应该新建类ProductIdComparer 内容如下:

使用的时候,只需要

结果如下:

<a href="http://images.cnblogs.com/cnblogs_com/LoveJenny/201108/201108011958544428.png"></a>

现在假设我们要 按照 Name来筛选重复呢?

很明显,需要再添加一个类ProductNameComparer.

那能不能使用泛型类呢??

新建类PropertyComparer&lt;T&gt; 继承IEqualityComparer&lt;T&gt; 内容如下:

主要是重写的Equals 和GetHashCode 使用了属性的值比较。

使用的时候,只需要:

<a href="http://images.cnblogs.com/cnblogs_com/LoveJenny/201108/201108011958586474.png"></a>

为什么微软不提供PropertyEquality&lt;T&gt; 这个类呢?

按照上面的逻辑,这个类应该没有很复杂啊,细心的同学可以发现PropertyEquality 大量的使用了反射。每次获取属性的值的时候,都在调用 

_PropertyInfo.GetValue(x, null);

可想而知,如果要筛选的记录非常多的话,那么性能无疑会受到影响。

为了提升性能,可以使用表达式树将反射调用改为委托调用,

具体代码如下:

可以看到现在获取值只需要getPropertyValueFunc(obj) 就可以了。

使用的时候:

本文转自LoveJenny博客园博客,原文链接:http://www.cnblogs.com/LoveJenny/archive/2011/08/01/2124233.html,如需转载请自行联系原作者