palermo4 posted on April 2, 2010 19:22

I recently wrote a blog post demonstrating how to define a class that allows equality to be based on the definition provided by the developer, not the .NET Framework.

To my surprise, I received comments, twitters, facebook posts, and emails all challenging my code sample.  Some of the information I received caused me to (ahem) update my code sample (see below).  However, some of the feedback made me wonder if the purpose behind overriding Equals is understood by some developers.  Reading someone’s opinion in a book is one thing.  Actually (and successfully) implementing working solutions doing it is another.

To begin with, let me make clear that the default implementation for equality of two reference types is to see if they are the same reference in memory itself.  If overriding the Equals method off of Object was considered taboo, then it wouldn’t be a virtual method.  As a developer, I may want control over default and ad-hoc behaviors of my objects when sorted, compared, or otherwise.

Take for example the Distinct extension method in the Enumerable class.  This could easily be called in a Linq statement, and comparing references to one another may not solve my business problem.  If my business scenario mandates that two (or more) students object instances are the same if each have the same ID, then so be it.  Business rules drive code – code does not drive business rules.  Whether or not someone agrees with the business rules is another matter.

Having said that, I do agree that the instance level data being used in the hash algorithm should be based on immutable data, so I revised the sample from the previous blog post to demonstrate that specific implementation.

public class Student : IEquatable<Student>
{
    public readonly int Id;
    public string FullName { get; set; }

    public Student(int id)
    {
        this.Id = id;
    }// ctor

    public override string ToString()
    {
        return string.Format("{0}: {1}",
            Id, FullName);
    }// method

    public override int GetHashCode()
    {
        return Id;
    }// method

    public override bool Equals(object obj)
    {
        Student other = obj as Student;
        return ((IEquatable<Student>)this).Equals(other);
    }// method

    bool IEquatable<Student>.Equals(Student other)
    {
        if (object.Equals(other, null)) return false;
        return (GetHashCode() == other.GetHashCode());
    }// explicit interface implementation

    public static bool operator ==(Student s1, Student s2)
    {
        if (Object.Equals(s1,null))
            return (Object.Equals(s2,null));
            return ((IEquatable<Student>)s1).Equals(s2);
    }// operator overload

    public static bool operator !=(Student s1, Student s2)
    {
        return !(s1 == s2);
    }// operator overload

}// class

Posted in: code  Tags:

Comments

Add comment




  Country flag

biuquote
  • Comment
  • Preview
Loading



Disclaimer
The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2010 J. Michael Palermo IV