在这种情况下,重写GetHashCode
函数的最佳方法是什么如果中至少有一个字段匹配,则认为my对象是相等的。
在通用Equals
方法的情况下,示例可能如下所示:
public bool Equals(Whatever other)
{
if (ReferenceEquals(null, other)) return false;
if (ReferenceEquals(this, other)) return true;
// Considering that the values can't be 'null' here.
return other.Id.Equals(Id) || Equals(other.Money, Money) ||
Equals(other.Code, Code);
}
尽管如此,我还是很困惑如何为这种情况制作一个好的GetHashCode
实现。
这应该怎么做?
谢谢。
这是Equals
的一个糟糕定义,因为它不是可传递的。
x = { Id = 1, Money = 0.1, Code = "X" }
y = { Id = 1, Money = 0.2, Code = "Y" }
z = { Id = 3, Money = 0.2, Code = "Z" }
x == y
和y == z
之后是x != z
。
此外,我们可以确定GetHashCode
的唯一合理实现是常数映射。
假设x
和y
是不同的对象。设z
为对象
z = { Id = x.Id, Money = y.Money, Code = "Z" }
然后x == z
和y == z
,使x.GetHashCode() == z.GetHashCode()
和y.GetHashCode() == z.GetHashCode()
建立x.GetHashCode() == y.GetHashCode()
。由于x
和y
是任意的,我们已经确定GetHashCode
是常数。
GetHashCode
的唯一可能实现是
private readonly int constant = 17;
public override int GetHashCode() {
return constant;
}
所有这些都清楚地表明,您需要重新考虑您正在尝试模型的概念,并提出Equals
的不同定义。
我认为你不应该使用等号。人们对相等的含义有着非常明确的概念,如果id不同但代码或名称相同,我不会认为它们是"相等的"。也许你需要一个不同的方法,比如"IsCompatible"。
如果您希望能够对它们进行分组,您可以在这些对象的列表上使用扩展方法tollookup()来使用谓词,该谓词将是您的IsCompatible方法。然后将它们分组。
黄金法则是:如果对象比较相等,它们必须产生相同的哈希码。
因此,一个符合(但我们说,不希望)的实现将是
public override int GetHashCode()
{
return 0;
}
坦率地说,如果Id
, Name
和Code
是相互独立的,那么我不知道你是否可以做得更好。把这种类型的对象放到哈希表中是很痛苦的。