您对此Person类有何看法?像那样覆盖Equals和GetHashCode是一个坏主意或最佳实践吗?
public class Person {
public int PersonId { get; set; }
public string Name { get; set; }
public override bool Equals(object obj) {
var person = obj as Person;
return PersonId == person.PersonId;
}
public override int GetHashCode() {
return PersonId;
}
}
用法:
static void Main(string[] args) {
var list = new List<Person>();
list.Add(new Person(){ PersonId = 1, Name = "Mike"});
list.Add(new Person() { PersonId = 2, Name = "Michael Sync" });
list.Add(new Person(){ PersonId = 1, Name = "Mike"});
var list1 = new List<Person>();
list1.Add(new Person() { PersonId = 1, Name = "Mike" });
list1.Add(new Person() { PersonId = 3, Name = "Julia" });
var except = list.Except(list1);
foreach (var item in except) {
Console.WriteLine(item.Name);
}
Console.ReadKey();
}
答案 0 :(得分:4)
几点:
它不是空安全或“不同类型”安全。试试这个:
new Person().Equals(new Object());
或
new Person().Equals(null);
邦。
定义相等操作的类应该通常是不可变的IMO。例如,在将对象用作字典键后更改对象的内容是一件坏事。
考虑实施IEquatable<Person>
快速重新实现,仍然假设您希望在ID上基于 完全基于
。public sealed class Person : IEquatable<Person> {
private readonly int personId;
public int PersonId { get { return personId; }
private readonly string name;
public string Name { get { return name; } }
public Person(int personId, string name) {
// Is a null name valid? If not, throw here.
this.personId = personId;
this.name = name;
}
public override bool Equals(object obj) {
return Equals(obj as Person);
}
public Equals(Person other) {
return other != null && other.personId == personId;
}
public override int GetHashCode() {
return personId;
}
}
答案 1 :(得分:4)
是的,这是错误的。您应该永远使用可变属性作为GetHashCode计算的一部分。这样做可以让您获得无数难以追踪的错误。
答案 2 :(得分:0)
我可以看到的一个问题是,你会得到很多新的(未保存的)记录(很多零)的冲突 - 除非你做那些连续的-ve id之类的东西......但是你真的需要使用Person
作为密钥吗?我个人认为我不会打扰......