(1)我知道GetHashCode
必须为两个对象返回相同的数字(如果它们相等)。Equalals中的SequenceEqual使GetHashCode中断
(2)我也知道,SequenceEqual
比较一List
的每个值,并Equals(list1, list2)
将返回true只有list1
和list2
是相同的实例。
所以,考虑下面的代码:
public List<ClassB> SampleList { get; set; }
public string Str { get; set; }
protected bool Equals(Uncorrectable other)
{
return Enumerable.SequenceEqual(this.SampleList, other.SampleList) && string.Equals(this.Str, other.Str);
}
public override bool Equals(object obj)
{
if (ReferenceEquals(null, obj)) { return false; }
if (ReferenceEquals(this, obj)) { return true; }
if (obj.GetType() != this.GetType()) { return false; }
return this.Equals((ClassA) obj);
}
public override int GetHashCode()
{
unchecked
{
return
((this.SampleList != null ? this.SampleList.GetHashCode() : 0)*397)^
(this.Str != null ? this.Str.GetHashCode() : 0);
}
}
我真的需要(用SequenceEqual
(2))这种行为Equals
,多为单元测试:使此代码Assert.AreEqual(classA1, classA2)
工作。
但我的一些代码,可能是在这种情况下
int hash1 = new List<ClassB>().GetHashCode();
int hash2 = new List<ClassB>().GetHashCode();
hash1
和hash2
因为破是不相等的。
所以在我的ClassA
,(1)是不尊重。
什么是最好的解决办法:
- 变化
ClassA.Equals
方法使用Equals(this.SampleList, other.SampleList)
,而不是Enumerable.SequenceEqual(this.SampleList, other.SampleList)
,改变了所有的考试 - 创建另一个
IEnumerable
的实现,其中Equals
压倒一切就像是SequenceEqual
- 修改
ClassA.GetHashCode
到请拨打GetHashCode
关于所有清单项目 - 什么也不做
- 另一个?
那么明显(我的某处大脑是**(1)**的倒数必须是真的)的想法。如果ClassA的设计不在大列表中(我只有10个不同的ClassA实例),并且我不需要性能,我们是否同意可以使用第二种解决方案(使用长度或其他字段)? – ZwoRmi
@ZwoRmi是的。请注意,计算一个大的'SampleList'的哈希通常可能会非常长...因此,举例来说,您甚至可以“作弊”并仅在哈希中包含固定的子集...'(this.SampleList.Count * 397)^ this.SampleList.Take(5).Aggregate' – xanatos
如果您完全忽略列表,那么碰撞率很可能会很高,导致使用散列码的任何情况都会导致性能很差。 – Servy