让我们考虑Polygon
课程。检查是否相等应该在大多数时间比较引用,但是在很多情况下值相等都很方便(比如将两个多边形与Assert.AreEqual
进行比较时)。
我的想法是让价值平等在某种程度上继承参考平等。在这种情况下,==operator
应该保留其默认的引用检查实现非常明显。
那么object.Equals()
和IEquatable<Polygon>.Equals()
呢? MSDN并不意味着==
和.Equals()
应该这样做,但仍然不会使Polygon
个对象的行为过于模糊?
此外,Polygon
类是可变的。
答案 0 :(得分:2)
MSDN几乎可以清楚
要检查参考相等性,请使用
ReferenceEquals
。 要检查 值相等,通常应使用Equals
。但是,等于它 由Object
实现只执行引用标识检查。它 因此,当您致电Equals
时,确认是否重要 type会覆盖它以提供值相等语义。当你创建 您自己的类型,您应该覆盖Equals
。
默认情况下,运算符
==
测试引用相等性 确定两个引用是否表示相同的对象,所以引用 类型不需要实现operator == 以获得此功能 功能。 当类型是不可变的时,表示包含的数据 实例无法更改,重载operator ==进行比较 值相等而不是引用相等可能很有用因为,as 不可变对象,只要它们可以被认为是相同的 具有相同的价值。 在非不可变类型中覆盖运算符==
不推荐。
IEquatable文档也很清楚
定义值类型或类实现的通用方法 创建一个特定于类型的方法来确定实例的相等性。
答案 1 :(得分:1)
在.NET(以及Java)中进行相等性测试的一个主要困难是,有两个有用的等价关系,每个都基于一个可以明智地询问任何类对象的问题,但.NET并不是一致的关于应由Equals
和GetHashCode
应该回答的问题或关系。问题是:
无论遇到什么情况,您是否会永远等同于某个特定参考所标识的对象。
您是否认为自己等同于某个特定参考所标识的对象,除非或直到引用您的某些内容会影响该等效性。
对于不可变对象,两个关系都应该测试值相等。对于可变对象,第一个问题应该测试引用等价,第二个问题应该测试值相等。对于一个不可变对象,它持有对一个可变类型的对象的引用,但没有人会变异,这两个问题都应该测试该封装对象的值相等。
我个人的建议是,可变对象不会覆盖Object.Equals,但是它们提供了一个静态属性,它返回一个IEqualityComparer
来测试值的相等性。这需要这样做
任何不可避免地封装可变对象的对象都必须这样做
让IEqualityComparer
能够报告封装的对象
价值等价关系本身,但有一个IEqualityComparer
可以将这些东西存储在例如提供了Dictionary
它们永远不会被修改。