加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

c# – 如果引用类型上的Equals的覆盖总是意味着值相等?

发布时间:2020-12-15 06:53:57 所属栏目:百科 来源:网络整理
导读:Equals()没有为引用类型做任何特殊的操作,将意味着引用相等(即相同的对象).如果我选择覆盖Equals()作为引用类型,那么它是否总是意味着两个对象的值是等效的? 考虑这个可变的Person类: class Person{ readonly int Id; string FirstName { get; set; } stri
Equals()没有为引用类型做任何特殊的操作,将意味着引用相等(即相同的对象).如果我选择覆盖Equals()作为引用类型,那么它是否总是意味着两个对象的值是等效的?

考虑这个可变的Person类:

class Person
{
    readonly int Id;

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

表示完全相同的人的两个对象将始终具有相同的Id,但是其他字段可能随时间(即,地址更改之前/之后)而不同.

对于这个对象,Equals可以被定义为意味着不同的东西:

>值平等:所有字段是相等的(两个对象表示同一个人,但是不同的地址将返回false)
>身份平等:身份相同(两个对象代表同一个人,但是不同的地址将返回真实)
>参考平等:即不执行Equals.

问题:这个课程中哪个(如果有的话)比较喜欢? (或者也许这个问题应该是,“这个类的大多数客户端如何期待Equals()的行为?”)

笔记:

>使用Value Equality使得在Hashset或Dictionary中更难使用这个类
>使用Identity Equality使Equals和= =操作符之间的关系变得奇怪(即,对于Equals(),两个Person对象(p1和p2)的检查返回true后,您可能仍然希望将引用更新为指向“较新” 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);

相关问题:

> 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

解决方法

是的,决定正确的规则是棘手的.在这里没有一个单一的“正确”答案,它将在很大程度上取决于上下文和偏好个人而言,我很少考虑很多,只是默认参考大多数常规POCO类的平等:

>当使用像Person这样的东西作为一个哈希集中的字典键的情况的数量是最小的

>并且当您这样做时,您可以提供一个遵循您希望遵循的实际规则的自定义比较器
>但大多数情况下,我会使用int id作为字典(等)中的关键字

>使用引用等式意味着x == y给出相同的结果,无论x / y是Person还是对象,或者在通用方法中都是T
>只要Equals和GetHashCode是兼容的,大多数事情只会解决问题,一个简单的方法是不要覆盖它们

但是请注意,我总是建议相反的值类型,即明确地覆盖Equals / GetHashCode;但是,编写一个结构体真的很少见

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读