首先覆盖概念,然后覆盖方法Equals
和GetHashCode
。
主要是我想出了这个“非常简单的代码”:
internal class Person
{
public string name;
public int age;
public string lname;
public Person(string name, int age, string lname)
{
this.name = name;
this.age = age;
this.lname = lname;
}
public override bool Equals(object obj)
{
var person = obj as Person;
if (person != null)
{
return person.age == this.age && person.name == this.name && person.lname == this.lname;
}
return false;
}
public override int GetHashCode()
{
return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();
}
}
虽然这很有效,但我的“合作开发者”Mr.Resharper给了我一些建议:
return this.age.GetHashCode() * this.name.GetHashCode() * this.lname.GetHashCode();
答案 0 :(得分:21)
总结评论中讨论的内容:
Hashing旨在为给定对象提供一个不会发生变化的值,无论发生什么变化 - 因此最好只依赖于GetHashCode方法中的只读字段。
首先,我建议只读取name
和lname
字段,因为它们在您的使用方案中可能不会改变。
对于age
,这是定期更改的内容,因此最好存储一个DateTime
的出生日期,这个日期永远不会改变。那么你也可以只读它。
答案 1 :(得分:3)
如果您更改了哈希计算中使用的字段的值,则在将对象添加到基于字典的哈希容器(例如Dictionary或HashSet)之后,实际上将破坏容器的内部状态。这是为什么?因为对象已基于其初始状态存储在与哈希值相对应的存储桶中。当状态改变时,例如修改了“年龄”后,该对象将继续存在于哈希容器中的旧存储桶中,尽管根据当前的哈希代码这不是正确的存储桶。这会导致非常凌乱的行为和很多头痛。我已经针对这个主题写了一个article,上面有一些非常具体的示例,因此您可能需要查看一下。