什么时候==覆盖.equals不同?我了解==和.equals之间的区别。这里还有很多其他问题可以详细解释差异,例如这个问题:.Equals和==this之间有什么区别:位相等等等。我的问题是:为什么他们两个(我意识到必须有一个非常好的理由)-他们似乎都在做同样的事情(除非以不同的方式覆盖)。什么时候==会以不同的方式重载.equals被覆盖?我的问题是:为什么他们两个(我知道必须有一个很好的理由),如果有一个很好的理由,它还没有向我解释。C#中的相等比较是一团糟,在我对C#的设计感到遗憾的事项列表中排名第9:http://www.informit.com/articles/article.aspx?p=2425867在数学上,相等是最简单的等价关系,应遵守以下规则:x==x应始终为真,x==y应始终与y==x相同,x==y和x!=y应始终相同如果x==yandy==z为真,则x==z必为真。C#的==和Equals机制不保证这些属性!(谢天谢地,ReferenceEquals保证了所有这一切。)正如Jon在他的回答中所说,==是根据两个操作数的编译时类型分派的,并根据IEquatable.Equals(对象)和.Equals(T)。.为什么这些调度机制都是正确的?平等不是偏袒左手的谓词,那么为什么有些而不是所有的实现都这样做呢?实际上我们想要的用户定义相等是一个多重方法,其中两个操作数的运行时类型具有相同的权重,但这不是C#中存在的概念。更糟糕的是,Equals和==被赋予不同的语义是很常见的——通常一个是引用相等,另一个是值相等。天真的开发人员没有理由知道哪个是哪个,或者它们是不同的。这是一个相当大的错误来源。当您意识到GetHashCode和Equals必须一致,但==不一致时,情况会变得更糟。我正在从头开始设计一种新语言,出于某种疯狂的原因我想要运算符重载——我不想这样做——然后我将设计一个更简单的系统。类似的东西:如果你在一个类型上实现IComparable,那么你会自动得到,,==,!=等,为你定义的运算符,并且它们被实现以便它们是一致的。即x必须具有x的语义以及!(x>y)的语义,并且x==y始终与y==x相同,依此类推。现在,如果你的问题真的是:我们到底是怎么陷入这个神圣的烂摊子的?然后我在2009年写了一些想法:https://blogs.msdn.microsoft.com/ericlippert/2009/04/09/double-your-dispatch-double-your-fun/TLDR是:框架设计者和语言设计者有不同目标和不同的约束条件,他们有时不会将这些因素考虑到他们的设计中以确保跨平台的一致、合理的体验。这是设计过程的失败。什么时候==会以不同的方式重载.equals被覆盖?除非我有一个非常不寻常的、非常充分的理由,否则我永远不会这样做。当我实现算术类型时,我总是将所有运算符实现为彼此一致。==在编译时是静态绑定的,因为运算符始终是静态的。您重载运算符-您无法覆盖它们。Equals(object)以多态方式执行,因为它被覆盖了。至于你想要它们的时间......引用类型通常会覆盖Equals但不要重载==。轻松区分“这两个引用引用同一对象”和“这两个引用引用同一对象”可能很有用。(当然,如果有必要,你可以像Eric在评论中指出的那样使用ReferenceEquals,这样更清晰。)你这样做时想要清楚,请注意。double对NaN值有这种行为;==(double,double)当任一操作数为NaN时将始终返回false,即使它们是相同的NaN。除非合同无效,否则Equals无法做到这一点。(诚??然,GetHashCode因不同的NaN值而损坏,但那是另一回事了……)我个人不记得曾经实施过它们来给出不同的结果。可能出现的一种情况是,当您有一个以前的代码库依赖于通过==的引用相等性时,但您决定要添加值相等性检查。一种方法是实现IEquatable,这很好,但现在假设所有现有代码都相同,只是为了引用?继承的Object.Equals是否应该与IEquatable.Equals工作方式不同?这不是一个简单的答案,因为理想情况下,您希望所有这些函数/运算符以一致的方式运行。对于BCL中发生这种情况的具体情况,请查看TimeZoneInfo。在那种特殊情况下,==和Object.Equals保持不变,但它不是显式的,这是最好的选择。顺便说一句,缓解上述问题的一种方法是使类不可变。在这种情况下,代码不太可能因先前依赖于引用相等性而被破坏,因为您无法通过引用改变实例并使先前的相等性检查无效。通常,您希望他们也这样做,尤其是当您的代码将被除您自己和您身边的人以外的任何人使用时。理想情况下,您希望遵循对使用您的代码的任何人随机违反行为的最小意外原则。话虽如此:重载相等通常不是一个好主意,除非类型是不可变的和密封的。如果你正处于必须提出问题的阶段,那么在任何其他情况下它被纠正的可能性很小。这有很多原因:A.Equals和GetHashCode一起使用来使字典和哈希集工作-如果您的实现不一致(或哈希码随时间变化),则可能是以下情况之一:B.您真的想做什么?通常,面向对象语言中对象的标识就是它的引用。因此,拥有两个具有不同引用的相同对象只会浪费内存。首先可能没有必要创建副本。C.当你开始实现对象的相等性时,你经常会发现你正在寻找“为特定目的”定义的相等性。这使得为??此目的燃烧您唯一的Equals成为一个非常糟糕的主意-最好定义不同的EqualityComparer以供使用。D.正如其他人所指出的,您重载了运算符但覆盖了方法。这意味着除非运算符调用方法,否则当有人尝试使用==并发现在错误的层次结构级别调用了错误的(意外的)方法时,可能会出现非常有趣和不一致的结果。以上是C#学习教程:==什么时候用不同的方式覆盖.equals?如果分享的所有内容对您有用,需要了解更多C#学习教程,希望您多多关注---本文收集自网络,不代表立场。如涉及侵权,请点击右侧联系管理员删除。如需转载请注明出处:
