应的Equals上的引用类型的覆盖总平均值相等?平均值、类型、Equals

2023-09-03 00:50:33 作者:﹌生活过得像句费话°

如果没有什么特别的引用类型,等于()将意味着引用相等(即同一个对象)。如果我选择覆盖等于()为引用类型,如果它总是意味着两个对象的值是相同的?

Without doing anything special for a reference type, Equals() would mean reference equality (i.e. same object). If I choose to override Equals() for a reference type, should it always mean that the values of the two objects are equivalent?

考虑这个可变类:

class Person
{
    readonly int Id;

    string FirstName { get; set; }
    string LastName { get; set; }
    string Address { get; set; }
    // ...
}

两个对象重新present完全相同的人总是有相同的编号,但其他领域可能之前是不同的时间(即/后地址变更)。

Two objects that represent the exact same person will always have the same Id, but the other fields might be different over time (i.e. before/after an address change).

有关此Object等可以被定义为是指不同的事情:

For this object Equals could be defined to mean different things:

的值相等:所有领域都是平等的(两个对象再presenting同一人,但不同的地址将返回false) 在身份平等 - IDS 是相等的(两个对象再presenting同一人,但不同的地址将返回true) 引用相等:即不实现equals 。 Value Equality: all fields are equal (two objects representing the same person but with different addresses would return false) Identity Equality: the Ids are equal (two objects representing the same person but with different addresses would return true) Reference Equality: i.e. don't implement Equals.

问:哪个(如果有的话),这些是preferable这个类? (也许这个问题应该是,怎么会这个类的大多数客户期望的equals()的行为?)

Question: Which (if any) of these is preferable for this class? (Or perhaps the question should be, "how would most clients of this class expect Equals() to behave?")

注:

使用值相等使得它在使用起来更加困难此一等级的Hashset 词典

使用身份平等,使两个Person对象(p1和p2)返回true,对检查后的Equals和 = 操作符怪(即之间的关系等于(),你可能仍然要更新引用指向更新Person对象,因为它不是值当量)。例如,下面的code读取奇怪 - 好像什么都不做,但它实际上是删除p1和p2的加入: Using Value Equality makes it more difficult to use this class in a Hashset or Dictionary

Using Identity Equality makes the relationship between Equals and the = operator strange (i.e. after a check of two Person objects (p1 and p2) returns true for Equals(), you might still want to update your reference to point to the "newer" Person object since it is not value equivalent). For example, the following code reads strange--seems like it does nothing, but it is actually removing p1 and adding p2:

HashSet<Person> people = new HashSet<Person>();
people.Add(p1);
// ... p2 is an new object that has the same Id as p1 but different Address
people.Remove(p2);
people.Add(p2);

相关问题:

Why微软是否建议跳过实现平等运营商对于引用类型? C#的``==和.Equals() When如果一个.NET类重载equals()?什么时候应该不是吗? Simplify重写的equals(),GetHash code()在C#中为更好的可维护性 Why does Microsoft recommend skip implementing equality operator for reference types? C# difference between `==` and .Equals() When Should a .NET Class Override Equals()? When Should it Not? Simplify Overriding Equals(), GetHashCode() in C# for Better Maintainability

推荐答案

是的,在决定这样做的正确的规则是棘手。没有单一的正确答案在这里,这将很大程度上取决于这两个方面和preference就个人而言,我很少费心考虑这个问题了,只是默认为引用的最正规的POCO类的平等:

Yes, deciding the right rules for this is tricky. There is no single "right" answer here, and it will depend a lot on both context and preference Personally, I rarely bother thinking about it much, just defaulting to reference equality on most regular POCO classes:

当你使用类似人的病例数作为字典键/哈希集是最小的 当你这样做,你可以提供一个自定义比较后面的实际的规则,你希望它遵循 ,但大部分的时间,我会使用简单的 INT编号作为字典键(等)的反正的 the number of cases when you use something like Person as a dictionary-key / in a hash-set is minimal and when you do, you can provide a custom comparer that follows the actual rules you want it to follow but most of the time, I'd use simply the int Id as the key in a dictionary (etc) anyway

请注意,但是,我总是劝的价值类型,即明确替换等于 / 相反GetHash code ;但随后,撰写结构是的真正的罕见

Note, however, that I would always advise the opposite for value-types, i.e. explicitly override Equals / GetHashCode; but then, writing a struct is really uncommon

 
精彩推荐