Labels

Monday, March 9, 2009

Equality Myth

Hi,

 

Sytstem.Object’s equality approach for compariong objects is really a Myth.

 

System.Object surprisingly supports three different methods for comparing objects for equality: ReferenceEquals() and two version of Equals().

Add to this the comparison operator (==), and we actually have Four Ways of comparing for equality.

 

ReferenceEquals():

 

·         Static Method – Works for Comparing References - Tests whether two references refer to the same instance of a class

·         Being Static – Cannot be overridden in order to compare Objects By Value - ‘Value Equality’.

 

·         Returns True - If supplied with two references refer to the same object instance, or both are null

·         Returns False - Otherwise.

 

SomeClass x, y;

x = new SomeClass();

y = new SomeClass();

bool B1 = ReferenceEquals(null, null); // returns true

bool B2 = ReferenceEquals(null,x); // returns false

bool B3 = ReferenceEquals(x, y); // returns false because x and y point to different objects

 

Virtual Equals()

 

·         Non - Static Method – Works for Comparing References.

·         Being Virtual - You can override it in your own classes in order to compare Objects By Value - ‘Value Equality’.

·         Note - Your override should never throw exceptions - Bcoz doing so could cause problems for certain other .NET base classes that internally call this method.

 

·         Returns True - If supplied with two references refer to the same object instance, or both are null

·         Throws exception -  When either of them is null.

·         Returns False – Otherwise.

 

Syntax:

public virtual bool Equals (Object obj)

 

SomeClass x, y;

x = new SomeClass();

y = new SomeClass();

bool B1 = x.Equals(y); // returns false

bool B1 = x.Equals(null); // throws exception

 

x=null;

y=null;

bool B1 = x.Equals(y); // returns true

 

 

Static Equals()

 

·         Static Method – Works for Comparing References.

·         Being Static – Cannot be overridden in order to compare Objects By Value - ‘Value Equality’.

 

However here is the Gotcha – While comparing if both references are non-null, then it calls the Virtual instance version of Equals().

This means that if you have overridden the instance version of Equals(), the effect is as if you were overriding the static version as well.

 

·         Returns True - If supplied with two references refer to the same object instance, or both are null

·         Returns False – Otherwise (Even when either of them is null).

 

Syntax:

public bool Equals (Object objA, Object objB)

 

SomeClass x, y;

x = new SomeClass();

y = new SomeClass();

 

bool B1 = ReferenceEquals(null, null); // returns true

bool B2 = ReferenceEquals(null,x); // returns false

bool B3 = ReferenceEquals(x, y); // returns false because x and y point to different objects

 

Comparision Operator

 

·         The comparison operator can be best seen as an intermediate option between strict value comparison and strict reference comparison.

·         In most cases, writing: means that you are comparing references.

 

bool b = (x == y); // x, y object references 

 

·         However, it is accepted that there are some classes whose meanings are more intuitive if they are treated as values.

·         In those cases, it is better to override the comparison operator to perform a value comparison.

 

 

Summary Table -

 

 

= =

RefererenceEquals(x,y)

Virtual Equals(x)

Static Equals(x,y)

Value Types

Check for Value Equality

Checks for Reference Equality.

 

Will always return false.

Reason: Boxing is required and hence boxing will result into two different objects.

Overridden for ValueTypes: Hence Checks for Value Equality.

 

But, But, But,,,, using ‘==’ for structs [Again a Value Type] willl result in compliation error as there is no overloaded version is present of ‘==’ for value types.

 

Reference Types

Check for Reference Equality & never checks objects based on their contents.

 

Will return False, if both objects are different.

 

Will return True, if both objects are same, i.e points to same location.

Check for Reference Equality & never checks objects based on their contents.

 

Will return False, if both objects are different.

 

Will return True, if both objects are same, i.e points to same location.

Check for Reference Equality & never checks objects based on their contents.

 

Will return False, if both objects are different.

 

Will return True, if both objects are same, i.e points to same location.

 

Will return false if either of them is null. – Not Sure

 

Check for Reference Equality & never checks objects ba[1]sed on their contents.

 

Will return False, if both objects are different. Or either if them is null.

 

Will return True, if both objects are same, i.e points to same location.

 

 

 

String Types

Same as Value Types

Overridden for String Types:  Hence Checks for Value Equality.

 

 

 

Regards,

Arun Manglick



[1]

No comments:

Post a Comment