Identity and Equality in .NET
by Matthew Wilson


Listing One

class SomeType
{
  private string m_string;
  private int    m_int;
  public override bool Equals(Object obj)
  {
    // Check against null
    if(obj == null)
    {
      return false;
    }
    else
    {
      // Check against different type
      if(this.GetType() != obj.GetType())
      {
        return false;
      }
      else
      {
        // Safely convert to "SomeType"
        SomeType  rhs = (SomeType)obj;

        // Compare values
        return (m_string == rhs.m_string && m_int == rhs.m_int);
      }
    }
  }
  ...
}


Listing Two

public sealed class SomeType
{
  ...
  public override bool Equals(Object obj)
  {
    // Check against null
    if(obj == null)
    {
      return false;
    }
    else
    {
      // Get if is a "SomeType"
      SomeType  rhs = obj as SomeType;
      if(Object.ReferenceEquals(rhs, null))
      {
        return false;
      }
      else
      {
        // Compare values if given instance of SomeType
        return (m_string == rhs.m_string && m_int == rhs.m_int);
      }
    }
  }
}


Listing Three

class SomeType
{
  ...
  public static bool operator ==(SomeType o1, SomeType o2)
  {
    return o1.Equals(o2);
  }
  public static bool operator !=(SomeType o1, SomeType o2)
  {
    return !o1.Equals(o2);
  }
  ...
}


Listing Four

class SomeType
{
  ...
  public static bool operator ==(SomeType o1, SomeType o2)
  {
    return Object.Equals(o1, o2);
  }
  public static bool operator !=(SomeType o1, SomeType o2)
  {
    return !Object.Equals(o1, o2);
  }
  ...
}


Listing Five

class SomeType
{
  ...
  public static bool operator ==(SomeType o1, SomeType o2)
  {
    return o1 == null ? false : o1.Equals(o2);
  }
  public static bool operator !=(SomeType o1, SomeType o2)
  {
    return o1 != null ? false : !o1.Equals(o2);
  }
  ...
}


Listing Six

class SomeType
{
  ...
  public static bool operator ==(SomeType o1, SomeType o2)
  {
    return o1 == null ? o2 == null : o1.Equals(o2);
  }
  public static bool operator !=(SomeType o1, SomeType o2)
  {
    return o1 != null ? o2 != null :!o1.Equals(o2);
  }
  ...
}
Listing Seven
class SomeType
{
  ...
  public static bool operator ==(WithAsInline o1, WithAsInline o2)
  {
    return (Object)o1 == null ? (Object)o2 == null : o1.Equals(o2);
  }
  public static bool operator !=(WithAsInline o1, WithAsInline o2)
  {
    return (Object)o1 == null ? (Object)o2 != null : !o1.Equals(o2);
  }
  ...
}


Listing Eight

using PerfCntrType =
                 SynSoft.Performance.PerformanceCounter;

. . .

PerfCntrType  counter = new PerfCntrType();
const int     CELEMENTS = 100000;
TestType[]    objects   = new TestType[CELEMENTS];

for(i = 0; i < CELEMENTS; ++i)
{
  const int mod = 512;

  objects[i] = new TestType("String #" + (i % mod), args);
}

counter.Start();
for(i = 0, k = 0; i < CELEMENTS; ++i)
{
  for(j = i + 1; j < CELEMENTS; ++j)
  {
    if(objects[i] == objects[j])
    {
      ++k;
    }
  }
}
counter.Stop();




