C#中Equals和GetHashCode使用及区别
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实现
下面我们创建一个学生类,从而进一步的实现我们对象数据的对比
publicclassStudent { publicstringName{get;set;} publicintAge{get;set;} }
通过如下代码我们将通过distinct方法实现我们的过滤.
classProgram { staticvoidMain(string[]args) { Liststudents=newList { newStudent{Name="MR.A",Age=32}, newStudent{Name="MR.B",Age=34}, newStudent{Name="MR.A",Age=32} }; Console.WriteLine("distinctStudentshasCount={0}",students.Distinct().Count());//distinctStudentshasCount=3 Console.ReadLine(); } }
我们需要达到的是忽略相同数据的对象,但是并没有达到我们如期的效果.因为是distinct默认比较的是对象的引用...所以这样达不到我们预期效果.那我们修改一下来实现我们预期效果.
在默认情况下Equals具有以下行为:
- 如果实例是引用类型,则只有引用相同时,Equals才会返回true。
- 如果实例是值类型,则仅当类型和值相同时,Equals才会返回true。
Distinct(IEnumerable,IEqualityComparer)
通过使用指定的IEqualityComparer对值进行比较,返回序列中的非重复元素.
类型参数
- TSourcesource的元素类型。
参数
- sourceIEnumerable要从中移除重复元素的序列。
- comparerIEqualityComparer用于比较值的IEqualityComparer。
返回
- IEnumerable
一个包含源序列中的非重复元素的IEnumerable。
我们来看如下代码片段
publicclassStudentComparator:EqualityComparer{ publicoverrideboolEquals(Studentx,Studenty) { returnx.Name==y.Name&&x.Age==y.Age; } publicoverrideintGetHashCode(Studentobj) { returnobj.Name.GetHashCode()*obj.Age; } }
上述代码片段如果两个Equals返回的true并且GetHashCode返回相同的哈希码,则认为两个对象相等.
重写Equals和GetHashCode
varstu1=newStudent{Name="MR.A",Age=32}; varstu2=newStudent{Name="MR.A",Age=32}; boolresult=stu1.Equals(stu2);//falsebecauseit'sreferenceEquals
上述代码片段执行后结果非预期效果.我们将进一步的去实现代码,以达到预期效果....
publicclassStudent { publicstringName{get;set;} publicintAge{get;set;} publicoverrideboolEquals(objectobj) { varstu=objasStudent; if(stu==null)returnfalse; returnName==stu.Name&&Age==stu.Age; } publicoverrideintGetHashCode() { returnName.GetHashCode()*Age; } } varstu1=newStudent{Name="MR.A",Age=32}; varstu2=newStudent{Name="MR.A",Age=32}; boolresult=stu1.Equals(stu2);//resultistrue
我们再使用LINQDistinct方法进行过滤和查询,同时将会检查Equals和GetHashCode
Liststudents=newList { newStudent{Name="MR.A",Age=32}, newStudent{Name="MR.B",Age=34}, newStudent{Name="MR.A",Age=32} }; Console.WriteLine("distinctStudentshasCount={0}",students.Distinct().Count());//distinctStudentshasCount=2
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持毛票票。
作者:@冯辉
出处:https://www.cnblogs.com/yyfh/p/12245916.html?utm_source=tuicool&utm_medium=referral
声明:本文内容来源于网络,版权归原作者所有,内容由互联网用户自发贡献自行上传,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任。如果您发现有涉嫌版权的内容,欢迎发送邮件至:czq8825#qq.com(发邮件时,请将#更换为@)进行举报,并提供相关证据,一经查实,本站将立刻删除涉嫌侵权内容。