一个== b当出现可能是假的,a.Equals(二)真的吗? [英] When can a == b be false and a.Equals(b) true?

查看:175
本文介绍了一个== b当出现可能是假的,a.Equals(二)真的吗?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我今天遇到了这种情况。我有一个对象,我测试是否相等;在Create()方法返回一个子类实现MyObject来的。

  myObject的一个= MyObject.Create();
为MyObject B = MyObject.Create();

A == B: //为假
a.Equals(B); // 是真的
 

请注意我也有过缠身的equals()在子类中实现,这确实一个非常基本的检查,看是否没有传入的对象为空,是子类的类型。如果这两个条件都满足时,对象被认为是相等的。

另外稍微奇怪的是,我的单元测试套件做了一些测试,类似于

  Assert.AreEqual(MyObject.Create(),MyObject.Create()); //绿条
 

和预期的结果是观察。因此,我想这NUnit的使用在幕后a.Equals(B),而不是一个== b以我承担了。

边注:我计划在.NET和Java的混合,所以我可能是我的期望/假设在这里混了。然而,我认为,一个== B以下一直在.NET中比在Java中那样,你经常要使用equals()方法来测试平等的工作。

更新这里的equals()的执行情况,要求:

 公众覆盖布尔等于(obj对象){
    返回的obj = NULL和放大器;!&安培; obj是MyObjectSubclass;
}
 

解决方案

之间的主要区别 == 等于 == (像所有经营者)是不是多态,而等于(像任何虚函数)是。

在默认情况下,引用类型将得到相同的结果为 == 等于,因为它们都比较参考。它也当然有可能code的运算符逻辑和等于逻辑完全不同,尽管这看起来荒谬的事情。使用 == (或任何)在一个较高的水平比所需的逻辑被声明操作者(换句话说,当,引用对象作为父类的最大疑难杂症来自那要么没有明确定义的操作者或定义它不同于真类)。在这种情况下的类,它的逻辑的引用的是用于经营,但逻辑等于来自任何类实际上对象的。

我要强调指出,一旦在你的问题中的信息,单凭是绝对没有理由认为或假定等于比较值与参考。这是很轻松创建这样一个类,但是这是的没有的语言规范。

后的问题编辑修改

您实施的等于将返回true的类的任何非空实例的。虽然语法让我觉得你没有,你可能会被混淆了 C#的关键字(这印证型)与在VB.NET中的关键字(这印证引用平等)。如果事实确实如此,那么你可以通过让在C#中明确提到比较 Object.ReferenceEquals(这一点,OBJ)

在任何情况下,这就是为什么你看到等于,因为你传递一个类的非空实例。

顺便说一下,关于NUnit的使用您的评论等于是真的出于同样的原因;因为运营商是不是多态的,就没有办法,如果使用了断言功能特定的类来定义自定义平等的行为 ==

I ran into this situation today. I have an object which I'm testing for equality; the Create() method returns a subclass implementation of MyObject.

MyObject a = MyObject.Create();
MyObject b = MyObject.Create();

a == b; // is false
a.Equals(b); // is true

Note I have also over-ridden Equals() in the subclass implementation, which does a very basic check to see whether or not the passed-in object is null and is of the subclass's type. If both those conditions are met, the objects are deemed to be equal.

The other slightly odd thing is that my unit test suite does some tests similar to

Assert.AreEqual(MyObject.Create(), MyObject.Create()); // Green bar

and the expected result is observed. Therefore I guess that NUnit uses a.Equals(b) under the covers, rather than a == b as I had assumed.

Side note: I program in a mixture of .NET and Java, so I might be mixing up my expectations/assumptions here. I thought, however, that a == b worked more consistently in .NET than it did in Java where you often have to use equals() to test equality.

UPDATE Here's the implementation of Equals(), as requested:

public override bool Equals(object obj) {
    return obj != null && obj is MyObjectSubclass;
}

解决方案

The key difference between == and Equals is that == (like all operators) is not polymorphic, while Equals (like any virtual function) is.

By default, reference types will get identical results for == and Equals, because they both compare references. It's also certainly possible to code your operator logic and Equals logic entirely differently, though that seems nonsensical to do. The biggest gotcha comes when using the == (or any) operator at a higher level than the desired logic is declared (in other words, referencing the object as a parent class that either doesn't explicitly define the operator or defines it differently than the true class). In such cases the logic for the class that it's referenced as is used for operators, but the logic for Equals comes from whatever class the object actually is.

I want to state emphatically that, based solely upon the information in your question, there is absolutely no reason to think or assume that Equals compares values versus references. It's trivially easy to create such a class, but this is not a language specification.

Post-question-edit edit

Your implementation of Equals will return true for any non-null instance of your class. Though the syntax makes me think that you aren't, you may be confusing the is C# keyword (which confirms type) with the is keyword in VB.NET (which confirms referential equality). If that is indeed the case, then you can make an explicit reference comparison in C# by using Object.ReferenceEquals(this, obj).

In any case, this is why you are seeing true for Equals, since you're passing in a non-null instance of your class.

Incidentally, your comment about NUnit using Equals is true for the same reason; because operators are not polymorphic, there would be no way for a particular class to define custom equality behavior if the Assert function used ==.

这篇关于一个== b当出现可能是假的,a.Equals(二)真的吗?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆