![](/img/trans.png)
[英]IEqualityComparer GetHashCode being called but Equals not
[英]Advantage of deriving external class from IEqualityComparer<> over overriding GetHashCode and Equals
我需要对成员变量而不是类进行散列,所以我不检查引用是否在字典中。 如果不覆盖默认值,它将找不到相同的Value
,但只有在找到与HashedType
完全相同的实例时才返回,这样代码就会失败。
Dictionary.Add(new HashedType(4));
Dictionary.Contains(new HashedType(4)); // fails to find 4
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);
}
}
}
看起来我可以覆盖GetHashCode()和Equals()为我这样做。
但是,MSDN建议我创建一个单独的类,我从IEqualityComparer派生并实例化我的字典使用HashedType和HashedTypeComparer:IEqualityComparer。
为了使这更容易,我从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(); }
}
这一切似乎都是人为的。
我获得的唯一优势是不改变Equals()?
我的意思是,实际上,我希望Equals能够与那个单一成员进行比较。
想法是object.Equals
是该类型的自然相等(并且GetHashCode
应该与该相等的概念相匹配)。 如果您希望在逐个案例的基础上获得不同的相等性,则使用IEqualityComparer
。
例如,考虑一个string
。 重写的Equals
和GetHashCode
方法执行区分大小写的比较。 但是如果你想要一个字典,其中键不区分大小写呢? 编写一个不区分大小写的IEqualityComparer
并将其传递给字典的构造函数。
您的示例听起来像HashedType
任何两个实例通常被视为相等,如果它们的成员相等。 在这种情况下,我建议你重写object.Equals
和object.GetHashCode
方法,而不是写IEqualityComparer
。
您选择其中一个的原因是您是否总是希望使用某个逻辑比较给定类型的实例,或者仅在这种情况下进行比较。
Equals
和GetHashCode
提供两个对象在逻辑上是否相等的“真实”实现。 IEqualityComparer
让你重写的情况下,逐案 ,以及独立的所有权(这可能是谁控制的实体与使用它们的代码不同的政党)。
想象一下,你不拥有基础类(即它是由另一个团队生成的,或者只是作为二进制文件给你)。 您始终可以创建IEqualityComparer
。 您可能无法更改Equals
和GetHashCode
...
如果大多数时候您希望字典行为默认工作,则覆盖GetHashCode和Equals。 请记住,要使它工作,它们必须永远不会在对象的生命周期中更改 - 所以如果它们运行了Value,则应在构造函数和只读属性中设置Value。
当你想在程序的一个部分中以不同的方式比较事物时,IEqualityComparer真的被用于。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.