Cinchoo – Simplified Object Equality

In this post I present a way to implement equality between objects. Implicit support for == and != operators. There is the big writeup on Guidelines for Overloading Equals() and Operator == (C# Programming Guide) at MSDN that you can follow when you implement Equals() method for your custom type. But Cinchoo framework provides easy way to accomplish this. Read below on how to do it.

Reference Types

The Equals method is just a virtual one defined in System.Object, and overridden by whichever classes choose to do so. By default it provides reference equality.

The == operator is an operator which can be overloaded by classes, but which usually has identity behavior. The == operator has not been overloaded, it compares whether two references refer to the same object – which is exactly what the implementation of Equals does in System.Object.

Cinchoo framework provides abstraction through ChoEquatableObject<T> class, which exposes Equals() method, == and != operators for you. The default implementation of Equals() method uses reflection to make the comparison. This can be overloaded in your derived class.

1. Add reference to Cinchoo.Core.dll assembly

2. Namespace Cinchoo.Core

For the sample class derived from ChoEuatableObject<T>, uses the default implementation of object equality

public class Security : ChoEquatableObject<Security>
{
    public string Symbol;
    [ChoIgnoreEqual]
    public double Price;
    [ChoIgnoreEqual]
    public int Qty;
}

ChoIgnoreEqual tell the framework to ignore those members while making equality of the objects. In the above Security class, it only uses Symbol member while making equality and ignore other members.

If you worry about performance of using reflection when making equality of objects, you can consider overriding Equals() method as below

public class Security : ChoEquatableObject<Security>
{
    public string Symbol;
    public double Price;
    public int Qty;

    public override bool Equals(Security other)
    {
        if (object.ReferenceEquals(other, null))
            return false;

        return Symbol == other.Symbol;
    }
}

The sample test code below

class Program
{
    static void Main(string[] args)
    {
        Security sec1 = new Security() { Symbol="AAPL", Price = 555.10, Qty = 10 };
        Security sec2 = new Security() { Symbol="AAPL", Price = 655.55, Qty = 500 };

        Console.WriteLine("ChoObject.Equals() : " + ChoObject.Equals(sec1, sec2));
        Console.WriteLine("Object.Equals() : " + sec1.Equals(sec2));
        Console.WriteLine("== operator: " + (sec1 == sec2));
        Console.WriteLine("!= operator: " + (sec1 != sec2));
    }
}

The output will be

ChoObject.Equals() : True
Object.Equals() : True
== operator: True
!= operator: False

In cases where you do not want to derive from ChoEquableObject<T> or your class already in the inheritance chain, please follow the next section in implementing object equality.

Value Types

Value types do not provide an overload for == by default. However, most of the value types provided by the framework provide their own overload. The default implementation of Equals for a value type is provided by ValueType , and uses reflection to make the comparison.

Below is the way to implement ValueType equality or a reference type equality through Interface

public struct Security : IEquatable<Security>
{
    public string Symbol;
    public double Price;
    public int Qty;

    #region IEquatable<Security> Members

    public override bool Equals(object obj)
    {
        return Equals((Security)obj);
    }

    public bool Equals(Security other)
    {
        if (object.ReferenceEquals(other, null))
            return false;

        return Symbol == other.Symbol;
    }

    public static bool operator ==(Security a, Security b)
    {
        return ChoObject.Equals(a, b);
    }

    public static bool operator !=(Security a, Security b)
    {
        return !ChoObject.Equals(a, b);
    }

    #endregion
}


Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google photo

You are commenting using your Google account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )

Connecting to %s