Friday, August 21, 2009

Equals Equals Vs. Equals

Recently I was asked, "What's the difference between 'a == b' and 'a.Equals(b)'. The short answer is that the second is a method call (easily overridden) and the first is not. While this is true, it's not the whole truth.

The real answer breaks down into two parts. First, for value types such as int, bool and float, the '==' is a direct comparison - it does compare the value of a and b. This is also true for 'string's, though these are a special case. For value types the '.Equals()' also compares the value of a and b because every value type can be treated as though it is boxed - .NET implicitly allows the class methods and properties to be called on their value type siblings.

For reference types - those created from classes, such as String, Int32, MyCarClass etc - the value comparison '==' cannot be called because an instance of a class is not the most primitive type of data the system can work with (in fact, Java calls value types 'primitives'.) In this case, the class must provide an 'Equals()' method - and every class does because all classes inherit from Object. However, because the default implementation (from Object) of 'Equals()' is to compare the references (ie: memory address value, not the data contained at that address), if 'Equals()' is not overridden you might find that two objects with the same value return false from Equals().

All the classes representing value types provide the appropriate Equals method (in that they all compare the value and not the reference of the object.) But for your own classes you must override Equals and provide your own implementation - because .NET does not implicitly know how to compare instances of your own classes. (It is possible to write reflection code which can do this, but it is long, difficult and prone to infallibility, so don't do it - unless you fancy a learning challenge ;)

So, in short (but not as short as earlier) the guide is:

For int: == compares the value, .Equals() compares the value (this is the .Equals() in Int32).
For Int32: == compares the value by calling the .Equals() in the Int32 class, .Equals() compares the value.
For MyInt32: == compares the references of the variables, .Equals() calls the method in your MyInt32 class.

If you want the '==' operator to perform a value comparison on instances of your own classes, you can use the 'operator' keyword and define your own '==' functionality;
For example, in a class called 'MyClass', if you have a working 'Equals()' method:

public static bool operator ==(MyClass a, MyClass b)
return a.Equals(b); // or whatever comparison you want to do

Another site with some code:

No comments:

Post a Comment