c#  Linq distinct不会调用Equals方法详解

我有以下课程

public class ModInfo : IEquatable<ModInfo>
{
 public int ID { get; set; }
 public string MD5 { get; set; }

 public bool Equals(ModInfo other)
 {
  return other.MD5.Equals(MD5);
 }

 public override int GetHashCode()
 {
  return MD5.GetHashCode();
 }
}

我使用如下方法将一些数据加载到该类的列表中:

public void ReloadEverything() {
 var beforeSort = new List<ModInfo>();
 // Bunch of loading from local sqlite database.
 // not included since it's reload boring to look at
 var modinfo = beforeSort.OrderBy(m => m.ID).AsEnumerable().Distinct().ToList();
}

问题是Distinct()调用似乎没有做到这一点.仍然存在彼此相等的对象.

根据这篇文章:https://msdn.microsoft.com/en-us/library/vstudio/bb348436%28v=vs.100%29.aspx

这就是你应该如何做出不同的工作,但它似乎并没有在ModInfo对象上调用Equals方法.

是什么导致这种情况发生?

示例值:

modinfo[0]: id=2069, MD5 =0AAEBF5D2937BDF78CB65807C0DC047C

modinfo[1]: id=2208, MD5 = 0AAEBF5D2937BDF78CB65807C0DC047C

我不关心选择哪个值,因为md5值相同,它们可能是相同的.

您还需要覆盖Object.Equals,而不仅仅是实现IEquatable.

如果你把它添加到你的班级:

public override bool Equals(object other)
{
 ModInfo mod = other as ModInfo;
 if (mod != null)
  return Equals(mod);
 return false;
}

它应该工作.

有关详细信息,请参阅此文章:Implementing IEquatable Properly

编辑:好的,这是基于GetHashCode的最佳实践的略有不同的实现.

public class ModInfo : IEquatable<ModInfo>
{
 public int ID { get; set; }
 public string MD5 { get; set; }

 public bool Equals(ModInfo other)
 {
  if (other == null) return false;
  return (this.MD5.Equals(other.MD5));
 }

 public override int GetHashCode()
 {
  unchecked
  {
   int hash = 13;
   hash = (hash * 7) + MD5.GetHashCode();
   return hash;
  }
 }

 public override bool Equals(object obj)
 {
  ModInfo other = obj as ModInfo;
  if (other != null)
  {
   return Equals(other);
  }
  else
  {
   return false;
  }
 }
}

你可以验证它:

ModInfo mod1 = new ModInfo {ID = 1, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};
ModInfo mod2 = new ModInfo {ID = 2, MD5 = "0AAEBF5D2937BDF78CB65807C0DC047C"};

// You should get true here
bool areEqual = mod1.Equals(mod2);

List<ModInfo> mods = new List<ModInfo> {mod1, mod2};

// You should get 1 result here
mods = mods.Distinct().ToList();

What's with those specific numbers in GetHashCode?

补充知识:C#中通过Distinct方法对List集合进行去重

在C#的List集合对象中,可以使用Distinct方法来对List集合元素进行去重,如果list集合内部元素为值类型,则Distinct方法根据值类型是否相等来判断去重,如果List集合内部元素为引用类型变量,则是判断相同引用的对象为相同进行List集合元素去重操作。

(1)值类型的List集合对象intList,内部元素为1,1,2,2,3,4,5等这几个元素。对intList对象进行去重可使用下列语句:

List intList= new List() { 1, 1,2,2,3,4,5};

intList= intList.Distinct().ToList();

经过上述Distinct方法去重处理并重新赋值后,intList集合内部元素为:1,2,3,4,5。

(2)针对引用类型的Distinct方法去重,则是判断List集合中的对象引用地址是否一致,不一致的话为不同的两个对象,即使2个对象的每个属性值都一样的情况下。

List testList = new List<ConsoleApplication1.TestModel>();
testList.Add(new TestModel()
{
Index=1,
Name=“Index1”
});
testList.Add(new TestModel()
{
Index = 2,
Name = “Index2”
});
testList.Add(new TestModel()
{
Index = 2,
Name = “Index2”
});
testList = testList.Distinct().ToList();

上述程序语句中,虽然List集合testList中的第2个元素和第3个元素的属性值完全一样,但这2个元素依旧是不同的对象,因此在调用Distinct()方法去重后重新赋值,testList依旧不变。

以上这篇c# Linq distinct不会调用Equals方法详解就是小编分享给大家的全部内容了,希望能给大家一个参考,也希望大家多多支持我们。

(0)

相关推荐

  • C#用表达式树构建动态查询的方法

    前文介绍了C#中表达式树的基本知识,在实际中,表达式树有很多用法,这里举几个例子,说明如何使用表达式树构建动态查询,从而扩展LINQ的查询方法. 在LINQ中,只要数据源实现了IQuerable<T>接口,表达式树就可以用来表示结构化查询.比如,LINQ提供了用来查询关系数据源的IQueryable<T>接口的实现,C#编译器在执行这类数据源查询时,会在运行时生成表达式树,然后,查询会遍历表达式树的数据结构,然后将其转换成针对特定数据源的合适的查询语言. 下面的几个例子演示了如何使

  • C# 实现Distinct将对象按条件去重

    平时,我们将c#中的Distinct大多用于对数组去重,一般数组为基础的数据类型,例如 int,string.也可以用于对象去重,我们看看C#对Distinct方法的定义: 有重载,第一个参数都加了this,是拓展方法,有关拓展方法,请百度了解. 下面我们来研究下Distinct的对象去重,假设我们现在有一个People类: public class People { public int ID { get; set; } /// <summary> /// 姓名 /// </summa

  • c# 动态构建LINQ查询表达式

    作者:精致码农 出处:http://cnblogs.com/willick 联系:liam.wang@live.com 最近工作中遇到一个这样的需求:在某个列表查询功能中,可以选择某个数字列(如商品单价.当天销售额.当月销售额等),再选择 小于或等于 和 大于或等于 ,再填写一个待比较的数值,对数据进行查询过滤. 如果只有一两个这样的数字列,那么使用 Entity Framework Core 可以这么写 LINQ 查询: public Task<List<Product>> Ge

  • c#  Linq distinct不会调用Equals方法详解

    我有以下课程 public class ModInfo : IEquatable<ModInfo> { public int ID { get; set; } public string MD5 { get; set; } public bool Equals(ModInfo other) { return other.MD5.Equals(MD5); } public override int GetHashCode() { return MD5.GetHashCode(); } } 我使用

  • 对vue中methods互相调用的方法详解

    如下所示: 最近在学习vue,并用vue+vue-router+axios+elementUI做了一个pos收银系统的前端页面,但是中间遇到methods里的方法调用问题.本身源码是没有调用的,但是我想直接调用多方便,结果出错了--然后百度了一波,终于解决了~ 分享并做个笔记. delAllOrderList:function(goods) { this.tableData = []; this.totalCount = 0; this.money = 0; }, checkout:functi

  • Android实现Activity、Service与Broadcaster三大组件之间互相调用的方法详解

    本文实例讲述了Android实现Activity.Service与Broadcaster三大组件之间互相调用的方法.分享给大家供大家参考,具体如下: 我们研究两个问题, 1.Service如何通过Broadcaster更改activity的一个TextView. (研究这个问题,考虑到Service从服务器端获得消息之后,将msg返回给activity) 2.Activity如何通过Binder调用Service的一个方法. (研究这个问题,考虑到与服务器端交互的动作,打包至Service,Ac

  • Java中的== 和equals()方法详解与实例

    Java中的== 和equals()方法: Java中的数据类型,可分为两类: 1.基本数据类型,也称原始数据类型. byte,short,char,int,long,float,double,boolean,他们之间的比较,应用双等号(==),比较的是他们的值. 2.引用数据类型(类) 当它们用(==)进行比较的时候,比较的是他们在内存中的存放地址,所以,除非是同一个new出来的对象,他们的比较后的结果为true,否则比较后结果为false. Java当中所有的类都是继承于Object这个基类

  • Java如何重写object类的equals方法详解

    1.Object类的equals()方法: 比较两个对象是否是同一个对象,equals() 方法比较两个对象,是判断两个对象引用指向的是同一个对象,即比较 2 个对象的内存地址是否相等.是则返回true Object类是所有类的父类,它的equals方法自然会被所有类继承,有一个子 类String对equals方法进行了覆盖(重写),使其具有了新功能 2.Object类的equals()方法与==没区别 Java.lang.String重写了equals()方法,把equals()方法的判断变为

  • python与C互相调用的方法详解

    前言 最近因为工作的需要,在考虑基于udp做一个用于网游战斗中的数据同步协议,为了前期测试数据,决定先做一个外部的代理tunnel,原理是在server端和client端分别建立网络转发proxy,即原来的C/S连接改为两个proxy之间数据快速传输.因为udp库是用C++写的代码,在测试数据的时候需要不断地修改参数,重新编译,修改输出统计数据制表等,不胜其烦,最终决定导出接口由python脚本来进行逻辑调用.下面话不多说,来一起看看详细的介绍: C/C++导出到python有多种方法,根据不同

  • JAVA发送http get/post请求,调用http接口、方法详解

    三个例子 -JAVA发送http get/post请求,调用http接口.方法 例1:使用 HttpClient (commons-httpclient-3.0.jar jar下载地址:http://xiazai.jb51.net/201904/yuanma/commons-httpclient-3.0.rar import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOE

  • java中重写equals()方法的同时要重写hashcode()方法(详解)

    object对象中的 public boolean equals(Object obj),对于任何非空引用值 x 和 y,当且仅当 x 和 y 引用同一个对象时,此方法才返回 true: 注意:当此方法被重写时,通常有必要重写 hashCode 方法,以维护 hashCode 方法的常规协定,该协定声明相等对象必须具有相等的哈希码.如下: (1) 当obj1.equals(obj2)为true时,obj1.hashCode() == obj2.hashCode()必须为true (2) 当obj

  • java集合——Java中的equals和hashCode方法详解

    Java中的equals方法和hashCode方法是Object中的,所以每个对象都是有这两个方法的,有时候我们需要实现特定需求,可能要重写这两个方法,今天就来介绍一些这两个方法的作用. equals()和hashCode()方法是用来在同一类中做比较用的,尤其是在容器里如set存放同一类对象时用来判断放入的对象是否重复. 这里我们首先要明白一个问题: equals()相等的两个对象,hashcode()一定相等,equals()不相等的两个对象,却并不能证明他们的hashcode()不相等.换

  • C#中调用DLL时未能加载文件或程序集错误的处理方法(详解)

    在加载DLL时,出现了如下的异常:未能加载文件或程序集"DMC3000, Version=1.0.0.0, Culture=neutral, PublicKeyToken=null"或它的某一个依赖项. 试图加载格式不正确的程序. 经上网查询后,其原因是x64和x86不兼容的问题.即DLL是x64的,但是VS默认生成的目标平台是x86的,因此,两者的不一致导致异常的出现. 其解决办法如下: 项目->属性->生成->目标平台->x64(与dll平台一致) 以上这篇

随机推荐