Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

When can a == b be false and a.Equals(b) true?

Tags:

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; } 
like image 734
alastairs Avatar asked Mar 22 '10 16:03

alastairs


People also ask

When would a == b return the same as A Equals B?

The Equals() and == operator are used for comparison and both returns the boolean value (true/false). For Value Type == and Equals() works in the same way, both compare two object by value. a==b and a. Equals(b) returns true , because in this case both compare two object by value.

What is the difference between a == b and a B?

a=b means you are TELLING system that a is equal to b a==b means you are ASKING the system wether a is equal to b or not? a=b is called assignment where the value of b is assigned to a. a==b is a condition checking or you can call it a comparison operator which checks whether the value of a and b are equal or not.

What's the difference between a == b and A Equals B in Java?

== is a operator to check again the references. b. Since equals is method in Object class it can be overridden and can be used to do anything, either to compare values inside the objects, compare references or calculate hash codes and compare them.

Is == the same as Equals?

== is an operator. equals() is a method of Object class. == should be used during reference comparison. == checks if both references points to same location or not.


2 Answers

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 ==.

like image 145
Adam Robinson Avatar answered Jun 14 '23 10:06

Adam Robinson


a == b checks if they reference the same object.

a.Equals(b) compares the contents.

This is a link to a Jon Skeet article from 2004 that explains it better.

like image 26
Arve Avatar answered Jun 14 '23 09:06

Arve