tags:

views:

850

answers:

4

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 ) ) );
}
+4  A: 

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.

Daniel LeCheminant
+2  A: 
  • Define what the identity means.. if reference identity then the default inherited equals will work.
  • If a value type (and thus value identity) you need to define.
  • If a class type, but has value semantics then define.

Likely you want to both override Equals(object) and define Equals(MyType) because the latter avoids boxing. And override the equality operator.

.NET Framework Guidelines book (2nd ed) has more coverage.

Richard
A: 

Lie Daniel L said,

public override bool Equals(object obj) {
    Point2 point = obj as Point2; // Point2? if Point2 is a struct
    return point != null && this.Equals(point);
}

public bool Equals(Point2 point) {
    ...
}
configurator
A: 
public override bool Equals ( object obj )
{
   // struct
   return obj  is Point2 && Equals (  ( Point2 ) value );
   // class
   //return Equals ( obj as Point2 );
}

public bool Equals ( Point2 obj )
baretta