简体   繁体   English

通过覆盖GetHashCode和Equals从IEqualityComparer <>派生外部类的优点

[英]Advantage of deriving external class from IEqualityComparer<> over overriding GetHashCode and Equals

I'm need to hash against a member variable instead of the class, so I don't check if the reference is in the dictionary. 我需要对成员变量而不是类进行散列,所以我不检查引用是否在字典中。 Without overriding the defaults, it won't find an identical Value , but only return if it finds the same exact instance of HashedType , such that this code fails. 如果不覆盖默认值,它将找不到相同的Value ,但只有在找到与HashedType完全相同的实例时才返回,这样代码就会失败。

Dictionary.Add(new HashedType(4));
Dictionary.Contains(new HashedType(4)); // fails to find 4

Definition of HashedType: HashedType的定义:

HashedType
{
   public HashedType(Int32 value) { Value = value); }
   public HashedType(String value) { Value = value); }
   public object Value;
   public void Serialize(Serializer s)
   {
      if (Value.GetType() == typeof(Int32)) 
      {
         s.Set<Int32>(0);
         s.Set<Int32>(Value);
      }
      else 
      {
         s.Set<Int32>(1);
         s.Set<String>(Value);
      }

   }
}

It looks like I can override GetHashCode() and Equals() to do this for me. 看起来我可以覆盖GetHashCode()和Equals()为我这样做。

However, MSDN recommends I create a separate class that I derive from IEqualityComparer and instantiate my dictionaries used HashedType with the HashedTypeComparer : IEqualityComparer. 但是,MSDN建议我创建一个单独的类,我从IEqualityComparer派生并实例化我的字典使用HashedType和HashedTypeComparer:IEqualityComparer。

To help make this easier, I've derived from Dictionary and created 为了使这更容易,我从Dictionary中派生并创建

HashedTypeDictionary<U> : Dictionary<T,U> 
{ 
   public HashedTypeDictionary() : base(new  HashedTypeComparer()) { } 
   public bool Equals(HashedType a, HashedType b) { return a.Value == b.Value; }
   publci int GetHashCode(HashedType a) { return a.Value.GetHashCode(); } 
}

This all seems contrived. 这一切似乎都是人为的。

Is the only advantage I get is not changing the Equals()? 我获得的唯一优势是不改变Equals()?

I mean, really speaking, I would want Equals to compare against that single member anyway. 我的意思是,实际上,我希望Equals能够与那个单一成员进行比较。

The idea is that object.Equals is the natural equality for that type (and GetHashCode should match that idea of equality). 想法是object.Equals是该类型的自然相等(并且GetHashCode应该与该相等的概念相匹配)。 IEqualityComparer is used when you want a different equality on a case-by-case basis. 如果您希望在逐个案例的基础上获得不同的相等性,则使用IEqualityComparer

Consider for example, a string . 例如,考虑一个string The overridden Equals & GetHashCode methods do case-sensitive comparisons. 重写的EqualsGetHashCode方法执行区分大小写的比较。 But what if you want a dictionary where the keys are not case-sensitive? 但是如果你想要一个字典,其中键不区分大小写呢? You write an IEqualityComparer that is not case-sensitive and pass it in the constructor of the dictionary. 编写一个不区分大小写的IEqualityComparer并将其传递给字典的构造函数。

Your examples sounds like any two instances of HashedType are to be normally treated as equal if their members are equal. 您的示例听起来像HashedType任何两个实例通常被视为相等,如果它们的成员相等。 In that case I'd recommend overriding the object.Equals and object.GetHashCode methods and not writing a IEqualityComparer . 在这种情况下,我建议你重写object.Equalsobject.GetHashCode方法,而不是写IEqualityComparer

The reason you would choose one over the other is whether you always want instances of a given type to be compared using a certain logic, or only in this one situation. 您选择其中一个的原因是您是否总是希望使用某个逻辑比较给定类型的实例,或者仅在这种情况下进行比较。

Equals and GetHashCode provide the "true" implementation of whether two objects are logically equal . EqualsGetHashCode提供两个对象在逻辑上是否相等的“真实”实现。 IEqualityComparer allows you to override that in a case-by-case basis , and to separate ownership (it might be different parties who control the entities versus the code using them). IEqualityComparer让你重写的情况下,逐案 ,以及独立的所有权(这可能是谁控制的实体与使用它们的代码不同的政党)。

Imagine, for a moment, that you don't own the underlying class (ie it's produced by another team, or only given to you as a binary). 想象一下,你不拥有基础类(即它是由另一个团队生成的,或者只是作为二进制文件给你)。 You always can create the IEqualityComparer . 始终可以创建IEqualityComparer You might not have the option of changing Equals and GetHashCode ... 您可能无法更改EqualsGetHashCode ...

If the majority of the time you want the Dictionary behavior to work by default override GetHashCode and Equals. 如果大多数时候您希望字典行为默认工作,则覆盖GetHashCode和Equals。 Bear in mind for this to work they must never change during the lifecycle of the object - so if they are running off Value then Value should be set in the constructor and a read-only property. 请记住,要使它工作,它们必须永远不会在对象的生命周期中更改 - 所以如果它们运行了Value,则应在构造函数和只读属性中设置Value。

IEqualityComparer is really used for when you want to compare things differently in one section of your program. 当你想在程序的一个部分中以不同的方式比较事物时,IEqualityComparer真的被用于。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 IEqualityComparer正在调用GetHashCode,但不是Equals - IEqualityComparer GetHashCode being called but Equals not 覆盖Equals和GetHashCode-派生类中的默认实现 - Overriding Equals and GetHashCode - default implementation in derived class 在IEqualityComparer上都不会调用Equals和GetHashCode - Neither Equals nor GetHashCode get called on IEqualityComparer 如果我的类实现了IEqualityComparer,我应该实现非通用GetHashCode和Equals吗? <T> ? - Should I implement non-generic GetHashCode and Equals if my class implements IEqualityComparer<T>? 覆盖类上的GetHashCode和Equals,因为它在字典中使用 - Overriding GetHashCode and Equals on a class because it's used in a dictionary 使用IEqualityComparer和Equals / GethashCode Override有什么区别? - What is the difference between using IEqualityComparer and Equals/GethashCode Override? 使用“external”GetHashCode和Equals for Dictionary - Use “external” GetHashCode and Equals for Dictionary 实现EqualityCompare与覆盖GetHashCode和Equals - Implementing EqualityCompare vs overriding GetHashCode and Equals 覆盖一个类型的Equals和GetHashCode,它有&#39;dibs&#39;? - Overriding the Equals and GetHashCode of a type, which has 'dibs'? C#,在重写GetHashCode和Equals时应考虑哪些类字段/成员? - C#, Which class fields/members should be considered when overriding GetHashCode and Equals?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM