C#中Equals和GetHashCode怎么用
创始人
2024-12-24 22:22:45
0次

Equals和GetHashCode

Equals每个实现都必须遵循以下约定:

自反性(Reflexive): x.equals(x)必须返回true.  对称性(Symmetric): x.equals(y)为true时,y.equals(x)也为true.  传递性(Transitive): 对于任何非null的应用值x,y和z,如果x.equals(y)返回true,并且y.equals(z)也返回true,那么x.equals(z)必须返回true.  一致性(Consistence): 如果多次将对象与另一个对象比较,结果始终相同.只要未修改x和y的应用对象,x.equals(y)连续调用x.equals(y)返回相同的值l.  非null(Non-null): 如果x不是null,y为null,则x.equals(y)必须为false

GetHashCode:

两个相等对象根据equals方法比较时相等,那么这两个对象中任意一个对象的hashcode方法都必须产生同样的整数。  在我们未对对象进行修改时,多次调用hashcode使用返回同一个整数.在同一个应用程序中多次执行,每次执行返回的整数可以不一致.  如果两个对象根据equals方法比较不相等时,那么调用这两个对象中任意一个对象的hashcode方法,不一同的整数。但不同的对象,产生不同整数,有可能提高散列表的性能.

IEqualityComparer实现

下面我们创建一个学生类,从而进一步的实现我们对象数据的对比

public class Student {  public string Name { get; set; }  public int Age { get; set; } }

通过如下代码我们将通过distinct方法实现我们的过滤.

class Program {  static void Main(string[] args)  {   List students = new List   {    new Student{ Name = "MR.A", Age = 32},    new Student{ Name = "MR.B", Age = 34},    new Student{ Name = "MR.A", Age = 32}    };   Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count());//distinctStudents has Count = 3   Console.ReadLine();  } }

我们需要达到的是忽略相同数据的对象,但是并没有达到我们如期的效果.因为是distinct默认比较的是对象的引用...所以这样达不到我们预期效果.那我们修改一下来实现我们预期效果.

在默认情况下Equals具有以下行为:

如果实例是引用类型,则只有引用相同时, Equals才会返回true。  如果实例是值类型,则仅当类型和值相同时, Equals才会返回true。

Distinct(IEnumerable, IEqualityComparer)

通过使用指定的 IEqualityComparer 对值进行比较,返回序列中的非重复元素.

类型参数

TSource source 的元素类型。

参数

source IEnumerable 要从中移除重复元素的序列。  comparer IEqualityComparer 用于比较值的 IEqualityComparer。

返回

IEnumerable

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

我们来看如下代码片段

public class StudentComparator : EqualityComparer {  public override bool Equals(Student x,Student y)  {   return x.Name == y.Name && x.Age == y.Age;  }  public override int GetHashCode(Student obj)  {   return obj.Name.GetHashCode() * obj.Age;  } }

上述代码片段如果两个Equals返回的true并且GetHashCode返回相同的哈希码,则认为两个对象相等.

重写Equals和GetHashCode

var stu1 = new Student { Name = "MR.A", Age = 32 };var stu2 = new Student { Name = "MR.A", Age = 32 };bool result = stu1.Equals(stu2); //false because it's reference Equals

上述代码片段执行后结果非预期效果.我们将进一步的去实现代码,以达到预期效果....

public class Student {  public string Name { get; set; }  public int Age { get; set; }  public override bool Equals(object obj)  {   var stu = obj as Student;   if (stu == null) return false;   return Name == stu.Name && Age == stu.Age;   }  public override int GetHashCode()  {   return Name.GetHashCode() * Age;  } }  var stu1 = new Student { Name = "MR.A", Age = 32 }; var stu2 = new Student { Name = "MR.A", Age = 32 }; bool result = stu1.Equals(stu2); //result is true

我们再使用LINQ Distinct方法进行过滤和查询,同时将会检查Equals和GetHashCode

List students = new List {  new Student{ Name = "MR.A", Age = 32},  new Student{ Name = "MR.B", Age = 34},  new Student{ Name = "MR.A", Age = 32} }; Console.WriteLine("distinctStudents has Count = {0}", students.Distinct().Count()); //distinctStudents has Count = 2

相关内容

热门资讯

空调连续工作多久需要停机休息 空调连续工作的时间取决于多个因素,包括空调的型号、功率、使用环境和维护情况等。一般来说,空调可以连续...
空调哪个符号是除湿的 空调除湿功能通常用一个水滴形状的符号表示。不同品牌和型号的空调遥控器可能会有所差异,但一般来说,除湿...
格力空调多长时间加一次氟利昂 1、一般情况下,空调对氟利昂的使用量是非常小的,所以在空调使用了四年左右的时候再考虑加也没问题。2、...
空调用多长时间需要加氟一次 一般情况下是五年。当出现以下这几种情况时,空调才需要加氟。1、空调的室内机和室外机各有两个接口,当接...
格调生活·C标思享荟:卡萨帝在... 9月12日的郑州龙湖金融岛,夜风轻拂,灯光璀璨。“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑...
品牌价值破千亿、高端份额持续领... 9月12日,“C标时刻共传奇——卡萨帝思享荟暨20周年品牌盛典郑州站”在郑州龙湖金融岛举办。2026...
空调主板坏了修800还是换新的 空调主板坏了是修还是换新,需要考虑多个因素,以下是一些建议:1. 维修成本:如果维修费用较低,比如 ...
空调开多久需要休息多长时间 问题:空调开多久需要休息多长时间回答:1、在使用空调的过程中,一般空调开7~8个小时左右需要休息2~...
中央空调多长时间清洗一次 1、一般空调开机前清洗一次即可,空调开机中间时段再清洗一次,空调关机时清洗一次,这样比较合理。2、空...
中央空调氟利昂多久加一次 看空调制热和制冷程度,很多人的观点认为氟利昂必须一年放一次,其实这个观点是错误的,理解上面有点偏差,...