2015-11-13 47 views
1

让我们考虑Polygon类。大多数情况下,检查平等是否应该比较参考值,但是在许多情况下,值相等会派上用场(例如,将两个多边形与Assert.AreEqual进行比较)。应该==运算符与Equals()完全相同吗?

我的想法是使参考平等的价值平等略为次要。在这种情况下,很明显==operator应该保持其默认引用检查实现。

那么object.Equals()IEquatable<Polygon>.Equals()呢? MSDN并不意味着==.Equals()应该这样做,但仍然 - 它不会使Polygon对象的行为过于模糊吗?

此外,Polygon类是可变的。

+0

他们是不一样的.'长期短''.Equals用于对象相等''==用于检查值的相等'做一个谷歌搜索更深入的澄清。为什么人们在这里问问题,他们可以很容易地找到答案买一个简单的谷歌搜索'我只是好奇' – MethodMan

+0

我不会在这里问这个问题的OP错误。我发现,与谷歌搜索相比,搜索引擎是获得知情答案的更有声誉的来源。而且,正如他所说,MSDN并不总是清楚这些事情。 –

+0

@MikeHofer问题不在于*上的主题*。 – Servy

回答

2

MSDN几乎是明确它

要检查引用相等,使用ReferenceEquals要检查价值相等的 ,您通常应该使用Equals。然而,等于 由Object执行只是执行参考身份检查。因此, 因此很重要,当您拨打Equals时,请验证 类型是否覆盖它以提供值相等语义。当您创建自己的类型 时,应该覆盖Equals


默认情况下,运营商==测试参考平等通过 确定两个引用是否表示相同的对象,所以引用 类型并不需要实现顺序==操作符以获得此功能 功能。 当类型是不可变的,这意味着包含在 实例中的数据不能被改变,重载运算符==比较 值相等,而不是参考平等可以是有用的因为,如 不可变的对象,它们可以被认为是只要它们的 具有相同的值。 非可变类型的覆盖运算符==是 不建议

IEquatable文档也很清楚

定义值类型或类实现来 创建用于确定实例平等类型特定的方法的一般化方法。

+0

我不想重写'=='。我问的是,在可变类中是否重写'.Equals()'(使其通过值进行比较)不会引入歧义。考虑到价值平等检查在意识形态上是参考检查的“次要”。 –

1

平等的测试在.NET(以及JAVA)的主要困难是,有两个有用的等价关系,各自基于可合理要求的任意类对象的问题,但。NET对于EqualsGetHashCode应该回答哪个问题或关系应该进行封装并不一致。这些问题是:

  1. 你会永远,永远等同于一些特定的引用标识的对象,无论发生什么事情给你。

  2. 您会认为自己等同于某个特定参考文献所标识的客体吗?除非或直到引用您的内容做了会影响该等同性的内容为止。

对于不可变对象,两个关系都应该测试值是否相等。对于可变对象,第一个问题应该测试引用等价性,第二个问题应该测试值相等。对于持有对可变类型对象的引用但不会有任何变异的不可变对象,这两个问题都应测试该封装对象的值相等。

我个人的建议是可变对象不重写Object.Equals,但它们提供一个静态属性,返回IEqualityComparer测试值的相等性。这就要求 是不可改变封装了可变对象必须 获取IEqualityComparer到能够报告已封装的对象的 价值的等价关系作为自己的,任何对象,但有一个IEqualityComparer 将使它可以存储这样的事情在例如一个Dictionary提供 他们从未被修改。

相关问题