C#实现 Linq 序列的Distinct—— IEnumerable<T>.Distinct<T>()——IEqualityComparer

简介

  在C#中使用List或者Collection的时候,我们经常需要使用到Distinct操作,但是微软默认提供的Distinct重载方法并不能满足我们的需求。这时候,我们就需要自己动手做一番工作了。

Distinct方法的重载

  Linq的Distinct的方法有如下一个重载版本:

public static IEnumerable<TSource> Distinc<TSource>(
    this IEnumerable<TSource> source,
    IEqualityComparer<TSource> comparer
)

  其中:

  类型参数

  TSource

    source中的元素类型;

  参数

  source

    类型: System.Collections.Generic.IEnumerable<TSource>

    要从中移除重复元素的序列

  comparer

    类型:System.Collections.Generic.IEqualityComparer<TSource>

    用于比较值的 IEqualityComparer<T>

  

  返回值

    类型:System.Collections.Generic.IEnumerable<TSource>

    一个 IEnumerable<T>,包含源序列中的非重复元素。

 

实现IEqualityComparer

  现在关键就是如何实现方法中的comparer 参数,我们希望做一个能够适用于各个类型的comparer,这样,我们就需要用到委托。

  好,话不多说,代码如下:

using System.Collections.Generic;

namespace MissTangProject.HelperClass
{
    public class ListComparer<T> : IEqualityComparer<T>
    {
        public delegate bool EqualsComparer<F>(F x, F y);

        public EqualsComparer<T> equalsComparer;

        public ListComparer(EqualsComparer<T> _euqlsComparer)
        {
            this.equalsComparer = _euqlsComparer;
        }

        public bool Equals(T x, T y)
        {
            if (null != equalsComparer)
            {
                return equalsComparer(x, y);
            }
            else
            {
                return false;
            }
        }

        public int GetHashCode(T obj)
        {
            return obj.ToString().GetHashCode();
        }
    }
}

使用Linq的Distinct方法

  假设我们有一个BoilerWorkerModel类,该类有一个code属性,使用方法如下:

  

List<BoilerWorkerModel> newList = _list1.Distinct(new ListComparer<BoilerWorkerModel>((p1, p2) => (p1.Code == p2.Code))).ToList();

  这样,我们就实现了能够适用于各个类型source的comparer了,可以随意的使用Linq的Distinct方法了!

  到这里,大功告成。

版权声明:本文为博主原创文章,未经博主允许不得转载。

时间: 2024-12-13 09:36:21

C#实现 Linq 序列的Distinct—— IEnumerable<T>.Distinct<T>()——IEqualityComparer的相关文章

编写高质量代码改善C#程序的157个建议——建议29:区别LINQ查询中的IEnumerable&lt;T&gt;和IQueryable&lt;T&gt;

建议29:区别LINQ查询中的IEnumerable<T>和IQueryable<T> LINQ查询一共提供了两类扩展方法,在System.Linq命名空间下,有两个静态类:Enumerable类,它针对继承了IEnumerable<T>接口的集合进行扩展:Queryable类,它针对继承了IQueryable<T>接口的集合类进行扩扎.接口IQueryable<T>也是继承了IEnumerable<T>接口的,所以,致使两个接口的方

如何解决linQ“序列不包含任何元素”的问题?

描述:该问题出现在校对BT种子数据的时候遇到的bug,原因是使用linq查找元素的时候 B是A的一个子集, B在A中一定存在,这种情况下就不会抛出异常情况,反之B的一部分不属于A就会异常应为B中的一个元素在A中查找是没有找到,此时使用First()就会有bug 用FirstOrDefault或者Find.First代表一定能找到,找不到就抛出异常:看看这个:http://q.cnblogs.com/q/23377/用FirstOrDefault或者Find. First代表一定能找到,找不到就抛

LINQ查询中的IEnumerable&lt;T&gt;和IQueryable&lt;T&gt;

LINQ查询方法一共提供了两种扩展方法,在System.Linq命名空间下,有两个静态类:Enumerable类,它针对继承了IEnumerable<T>接口的集合进行扩展:Queryable类,针对继承了IQueryable<T>接口的集合进行扩展.我们会发现接口IQueryable<T>实际也是继承了IEnumerable<T>接口的,既然这样微软为什么要设计出两套扩展方法呢? 从LINQ查询功能上我们知道实际上可以分为三类:LINQ to OBJECT

Spoj-DISUBSTR - Distinct Substrings~New Distinct Substrings SPOJ - SUBST1~(后缀数组求解子串个数)

Spoj-DISUBSTR - Distinct Substrings New Distinct Substrings SPOJ - SUBST1 我是根据kuangbin的后缀数组专题来的 这两题题意一样求解字符串中不同字串的个数: 这个属于后缀数组最基本的应用 给定一个字符串,求不相同的子串的个数. 算法分析: 每个子串一定是某个后缀的前缀,那么原问题等价于求所有后缀之间的不相同的前缀的个数. 如果所有的后缀按照 suffix(sa[1]), suffix(sa[2]), suffix(sa

LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg (转)

Select/Distinct操作符 适用场景:o(∩_∩)o- 查询呗. 说明:和SQL命令中的select作用相似但位置不同,查询表达式中的select及所接子句是放在表达式最后并把子句中的变量也就是结果返回回来:延迟. Select/Distinct操作包括9种形式,分别为简单用法. 匿名类型形式.条件形式.指定类型形式.筛选形式.整形类型形式. 嵌套类型形式.本地方法调用形式.Distinct形式. 1.简单用法: 这个示例返回仅含客户联系人姓名的序列. var q = from c i

LINQ to SQL语句之Select/Distinct和Count/Sum/Min/Max/Avg

上一篇讲述了LINQ,顺便说了一下Where操作,这篇开始我们继续说LINQ to SQL语句,目的让大家从语句的角度了解LINQ,LINQ包括LINQ to Objects.LINQ to DataSets.LINQ to SQL.LINQ to Entities.LINQ to XML,但是相对来说LINQ to SQL在我们程序中使用最多,毕竟所有的数据都要在数据库运行着各种操作.所以先来学习LINQ to SQL,其它的都差不多了,那么就从Select说起吧,这个在编写程序中也最为常用.

使用Linq中的Distinct方法对序列进行去重操作

使用Linq提供的扩展方法Distinct可以去除序列中的重复元素. 该方法具有以下两种重载形式: (1)public static IEnumerable<TSource> Distinct<TSource>(this IEnumerable<TSource> source) (重载1) 通过使用默认的相等比较器对值进行比较并返回序列中的非重复元素. (2)publicstatic IQueryable<TSource> Distinct<TSour

linq Distinct 去除重复数据

转载:http://www.cnblogs.com/ldp615/archive/2011/08/01/distinct-entension.html 只可惜linq默认不支持.Distinct(p => p.ID); 试想如果能写成下面的样子,是不是更简单优雅: var p1 = products.Distinct(p => p.ID); var p2 = products.Distinct(p => p.Name); 使用一个简单的 lambda 作为参数,也符合 Linq 一贯的风

Linq使用Distinct删除重复数据时如何指定所要依据的成员属性zz

最近项目中在用Linq Distinct想要将重复的资料去除时,发现它跟Any之类的方法有点不太一样,不能很直觉的在呼叫时直接带入重复数据判断的处理逻辑,所以当我们要用某个成员属性做重复数据的判断时,就必需绕一下路,这边稍微将处理的方法做个整理并记录一下. 首先为了方便接下去说明,我们必须先来准备后面会用到的数据类别,这边一样用笔者最常用来示范的Person类别,内含两个成员属性ID与Name. view source print? 01.public struct Person 02.{ 03