gpt4 book ai didi

c# - 在引用类型上重写 Equals 是否应该始终意味着值相等?

转载 作者:可可西里 更新时间:2023-11-01 08:38:11 25 4
gpt4 key购买 nike

在不对引用类型做任何特殊处理的情况下,Equals()将意味着引用相等(即相同的对象)。如果我选择覆盖 Equals()对于引用类型,它是否总是意味着两个对象的值是等价的?

考虑这个可变的 Person类:

class Person
{
readonly int Id;

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

代表同一个人的两个对象将始终具有相同的 Id ,但其他字段可能会随着时间的推移而有所不同(即在地址更改之前/之后)。

对于这个对象,Equals 可以定义为不同的意思:

  • 值相等:所有字段都相等(代表同一个人但地址不同的两个对象将返回 false)
  • 身份平等:Ids相等(代表同一个人但具有不同地址的两个对象将返回 true)
  • 引用平等:即不实现平等。

问题:哪些(如果有的话)更适合这门课? (或者也许问题应该是,“这个类的大多数客户期望 Equals() 表现如何?”)

注意事项:

  • 使用值平等使得在 Hashset 中使用此类变得更加困难或 Dictionary
  • 使用恒等式建立 Equals 和 = 之间的关系operator strange (即在检查两个 Person 对象(p1 和 p2)后返回 true 为 Equals() ,您可能仍想更新您的引用以指向“较新的”Person 对象,因为它不是值等价的)。例如,下面的代码读起来很奇怪——看起来什么也没做,但它实际上是删除 p1 并添加 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);

相关问题:

最佳答案

是的,为此确定正确的规则很棘手。这里没有单一的“正确”答案,这在很大程度上取决于上下文和偏好就个人而言,我很少考虑太多,只是默认在大多数常规 POCO 类上引用相等性:

  • 在哈希集中使用Person 作为字典键/的情况很少
    • 当你这样做时,你可以提供一个自定义比较器,它遵循你希望它遵循的实际规则
    • 但大多数时候,我会简单地使用 int Id 作为字典(等)中的键 无论如何
  • 使用引用相等意味着无论 x/yPersonx==y 都会给出相同的结果或 object,或者在泛型方法中确实是 T
  • 只要 EqualsGetHashCode 兼容,大多数事情都会解决,一个简单的方法是不覆盖它们

但是请注意,对于值类型,我总是建议相反的做法,即显式覆盖Equals/GetHashCode;但是,编写 struct 真的并不常见

关于c# - 在引用类型上重写 Equals 是否应该始终意味着值相等?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17573720/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com