[英]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. 重写的
Equals
和GetHashCode
方法执行区分大小写的比较。 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.Equals
和object.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 . Equals
和GetHashCode
提供两个对象在逻辑上是否相等的“真实”实现。 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
... 您可能无法更改
Equals
和GetHashCode
...
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.