Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How to best implement Equals for custom types?

Tags:

c#

.net

class

Say for a Point2 class, and the following Equals:

public override bool Equals ( object obj )  public bool Equals ( Point2 obj ) 

This is the one that is shown in the Effective C# 3:

public override bool Equals ( object obj ) {     // STEP 1: Check for null     if ( obj == null )     {         return false;     }      // STEP 3: equivalent data types     if ( this.GetType ( ) != obj.GetType ( ) )     {         return false;     }     return Equals ( ( Point2 ) obj ); }  public bool Equals ( Point2 obj ) {     // STEP 1: Check for null if nullable (e.g., a reference type)     if ( obj == null )     {         return false;     }     // STEP 2: Check for ReferenceEquals if this is a reference type     if ( ReferenceEquals ( this, obj ) )     {         return true;     }     // STEP 4: Possibly check for equivalent hash codes     if ( this.GetHashCode ( ) != obj.GetHashCode ( ) )     {         return false;     }     // STEP 5: Check base.Equals if base overrides Equals()     System.Diagnostics.Debug.Assert (         base.GetType ( ) != typeof ( object ) );      if ( !base.Equals ( obj ) )     {         return false;     }      // STEP 6: Compare identifying fields for equality.     return ( ( this.X.Equals ( obj.X ) ) && ( this.Y.Equals ( obj.Y ) ) ); } 
like image 759
Joan Venge Avatar asked Feb 19 '09 22:02

Joan Venge


People also ask

What is the GetType method typically used for inside the implementation of Equals?

The Point. Equals method calls the GetType method to determine whether the run-time types of the two objects are identical.

What is the difference between Equals () and == in C#?

The Equality Operator ( ==) is the comparison operator and the Equals() method in C# is used to compare the content of a string. The Equals() method compares only content.


2 Answers

In the one that takes an obj, if the type of obj is Point2, call the type specific Equals. Inside the type specific Equals, make sure that all the members have the same value.

public override bool Equals ( object obj ) {    return Equals(obj as Point2); }  public bool Equals ( Point2 obj ) {    return obj != null && obj.X == this.X && obj.Y == this.Y ...     // Or whatever you think qualifies as the objects being equal. } 

You probably ought to override GetHashCode as well to make sure that objects that are "equal" have the same hash code.

like image 133
Daniel LeCheminant Avatar answered Sep 28 '22 14:09

Daniel LeCheminant


There is a whole set of guidelines on MSDN as well. You should read them well, it is both tricky and important.

A few points I found most helpful:

  • Value Types don't have Identity, so in a struct Point you will usually do a member by member compare.

  • Reference Types usually do have identity, and therefore the Equals test usually stops at ReferenceEquals (the default, no need to override). But there are exceptions, like string and your class Point2, where an object has no useful identity and then you override the Equality members to provide your own semantics. In that situation, follow the guidelines to get through the null and other-type cases first.

  • And there are good reasons to keep GethashCode() and operator== in sync as well.

like image 41
Henk Holterman Avatar answered Sep 28 '22 12:09

Henk Holterman