当前位置: 首页 > 编程语言 > C#

使用IEqualityComparer和Equals-GethashCodeOverride有什么区别?分享

时间:2023-04-10 19:41:16 C#

使用IEqualityComparer和Equals/GethashCodeOverride有什么区别?当我使用字典时,有时我必须更改默认的等号含义才能比较键。我看到如果我在键的类上覆盖Equals和GetHashCode,或者如果我创建一个实现IEqualityComparer的新类,我会得到相同的结果。那么使用IEqualityComparer和Equals/GethashCodeOverride有什么区别?两个例子:classCustomer{publicstringname;公共年龄;publicCustomer(stringn,inta){this.age=a;这个.name=n;}publicoverrideboolEquals(objectobj){Customerc=(Customer)obj;returnthis.name==c.name&&this.age==c.age;}publicoverrideintGetHashCode(){return(this.name+";"+this.age).GetHashCode();}}classProgram{staticvoidMain(string[]args){Customerc1=newCustomer("MArk",21);Customerc2=newCustomer("MArk",21);字典d=新字典();控制台.WriteLine(c1.Equals(c2));试试{d.Add(c1,"Joe");d.Add(c2,"hil");foreach(KeyValuePairkind){Console.WriteLine(k.Key.name+";"+k.Value);}}catch(ArgumentException){Console.WriteLine("Chiavegiàinseritainpredenza");}最后{Console.ReadLine();}}}}第二个:classCustomer{publicstringname;公共年龄;publicCustomer(stringn,inta){this.age=A;这个.name=n;}}classDicEqualityComparer:EqualityComparer{publicoverrideboolEquals(Customerx,Customery)//等于dell'equalitycomparer{returnx.name==y.name&&x.age==y.年龄;}publicoverrideintGetHashCode(Customerobj){return(obj.name+";"+obj.age).GetHashCode();}}classProgram{staticvoidMain(string[]args){Customerc1=newCustomer("MArk",21);Customerc2=newCustomer("MArk",21);DicEqualityComparerdic=newDicEqualityComparer();字典d=新字典(dic);Console.WriteLine(c1.Equals(c2));试试{d.Add(c1,"Joe");d.Add(c2,"hil");foreach(KeyValuePairkind){Console.WriteLine(k.Key.name+";"+k.Value);}}catch(ArgumentException){Console.WriteLine("Chiavegiàinsertitainpredenza");}最后{Console.ReadLine();}}}}这两个例子有相同的结果提前致谢。当您覆盖Equals和GetHashCode时,您正在更改对象确定它是否等于另一个对象的方式。请注意,如果您使用==运算符来比较对象,除非您也重写该运算符,否则它不会具有与Equals相同的行为。这样做会改变单个类的行为,如果您需要为其他类提供相同的逻辑怎么办?如果你需要“普遍比较”。这就是您拥有IEqualityComparer的原因。看看这个例子:interfaceICustom{intKey{get;放;}}自定义类:ICustom{publicintKey{get;放;}publicint值{得到;放;}}classAnother:ICustom{publicintKey{get;放;}}classDicEqualityComparer:IEqualityComparer{publicboolEquals(ICustomx,ICustomy){returnx.Key==y.Key;}publicintGetHashCode(ICustomobj){returnobj.Key;我有两个不同的类都可以使用相同的比较器。vara=newCustom{Key=1,Value=2};varb=newCustom{Key=1,Value=2};varc=newCustom{Key=2,Value=2};varanother=newAnother{Key=2};vard=newDictionary(newDicEqualityComparer());d.Add(a,"X");//d.Add(b,"X");//同键异常d.Add(c,"X");//d.Add(另一个,"X");//相同的键异常请注意,我不必在两个类中重写Equals和GetHashCode。我可以在任何实现ICustom的对象中使用这个比较器,而不必重写比较逻辑。我还可以为“父类”创建一个IEqualityComparer并将其用于继承类。我可以让比较器的行为有所不同,我可以用一个比较值而不是键来比较。因此,IEqualityComparer提供了更大的灵活性,您可以实施通用解决方案。对象的Equals()GetHashCode()实现了对象固有的相等性概念。但是,您可能希望使用相等的替代概念-例如,地址对象的相等比较器仅使用邮政编码而不是完整地址。为此,它基本上是相同的,只有一个细微的差别。在第一个示例中,您使用Object类型的参数覆盖Equals,然后必须将其强制转换为Customer,但是,在第二个示例中,您可以使用Customer类型的参数,这意味着不需要强制转换。这意味着覆盖Equals允许比较两个不同类型的对象(在某些情况下可能需要),但是,实现IEqualityComparer并不能提供这种自由(在某些情况下也可能需要)。在许多情况下,人们可能希望使用不是100%等效的东西来使用Dictionary定位对象。举一个简单的例子,人们可能希望有一个以不区分大小写的方式进行匹配的字典。实现此目的的一种方法是将字符串转换为规范的大写,然后再将其存储在字典中或执行查找。另一种方法是为字典提供一个IEqualityComparer,它将计算哈希码并在某种大小写无关的函数中检查是否相等。在某些情况下,将字符串转换为其规范形式并尽可能使用该形式会更有效,但在其他情况下,仅以其原始形式存储字符串会更有效。我希望.NET改进这些字典的实用性的一个功能是请求与给定键相关联的实际键对象的方法(因此如果字典包含字符串“WowZo”作为键,您可以查找“wowzo”并获得“WowZo”;不幸的是,如果TValue不包含冗余引用,则检索实际键对象的唯一方法是枚举整个集合。另一种情况,当对象持有引用时,另一种比较方法可能很有用一个可变类型的实例,但永远不要将该实例暴露给任何可能改变它的东西。通常,包含相同值序列的两个int[]实例将不可互换,因为一个或两个可能被更改为包含不同的值未来。另一方面,如果使用字典来保存和查找int[]值,则每个字段将是对宇宙中任何int[]实例的唯一引用,并且如果没有实例被修改或暴露给外部代码,将相同的数组视为具有相同的值序列可能很有用。由于Array.Equals测试严格相等(引用相等),因此有必要使用一些其他方法来测试数组相等。以上就是C#学习教程:使用IEqualityComparer和Equals/GethashCodeOverride有什么区别?如果所有分享的内容对你有用,需要进一步了解C#学习教程,希望大家多多关注。本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处: