据我所知,只有在需要值相等语义时才需要覆盖它们。 System.Object 实现并不“坏”,它只是做一个引用检查(这是该级别的所有实现都可以做的)。
简而言之:如果您需要某种基于值的相等性(基于类属性的相等性),那么可以,覆盖掉。否则,它应该已经很好了。
编辑:
在上述情况下,您只需需要覆盖它们。如果你覆盖一个,你确实需要覆盖两者,原因很明显(它们需要保持一致等)。您可以出于其他答案中指出的其他原因(例如使用哈希值的算法的性能,即Dictionary 键等)在每个类上覆盖它们,但您不需要,默认的System.Object 实现将正常工作。
编辑 2:
要求提供更多信息,所以这里。考虑以下伪类:
public class User {
private int _id;
private string _username;
public string Username { get {return _username;}};
// [snip] Whatever other properties we might like to have.
public User(string username) {
// Initialise our user from a database, or whatever.
}
}
就目前而言,以下代码可能看起来很直观:
User foo = new User("me");
User bar = new User("me");
User baz = foo;
if (foo.Equals(bar)) {
Console.WriteLine("1: Success!");
}
if (foo.Equals(baz)) {
Console.WriteLine("2: Success!");
}
但它只会打印出来:
2:成功
为什么? foo 和 bar 是该类的两个单独实例,并且具有单独的引用。引用就像 C/C++ 中的指针。 foo 和 baz 是相同的引用,因为一个是从另一个分配的。不过,它们都有相同的值,用户称为“我”。基于值的.Equals 实现的示例实现可能是:
partial class User {
public override bool Equals(object b) {
if (b == null) return false;
if (b.GetType() != this.GetType()) return false;
// Now the heavy lifting
User other = (User)b;
if (other._id == this._id) return true;
else return false;
}
}
看看它是如何检查类的部分属性以确定相等性的吗?这就是工作中的价值平等。引用相等只是一个简单的this == b 检查。