Search code examples
c#comparison-operatorsicomparable

Define how a comparison operator is applied to a type?


How can I define whether and how a comparison operator is applied to operands of my type?


Solution

  • You implement the IComparable interface with the CompareTo method.

    To use all of the operators, try this:

    public sealed class Foo : IEquatable<Foo>, IComparable<Foo>
    {
        public static int Compare(Foo first, Foo second)
        {
            if (Object.ReferenceEquals(first, null))
                return (Object.ReferenceEquals(second, null) ? 0 : -1);
    
            return first.CompareTo(second);
        }
        public static bool operator==(Foo first, Foo second)
        {
            return Object.Equals(first, second);
        }
        public static bool operator!=(Foo first, Foo second)
        {
            return !Object.Equals(first, second);
        }
        public static bool operator<(Foo first, Foo second)
        {
            return Foo.Compare(first, second) < 0;
        }
        public static bool operator >(Foo first, Foo second)
        {
            return Foo.Compare(first, second) > 0;
        }
        public static bool operator <=(Foo first, Foo second)
        {
            return Foo.Compare(first, second) <= 0;
        }
        public static bool operator >=(Foo first, Foo second)
        {
            return Foo.Compare(first, second) >= 0;
        }
    
        private string bar;
    
        public string Bar
        {
            //getter and setter
        }
    
       public bool Equals(Foo other)
        {
            if (Object.ReferenceEquals(other, null))
                return false;
            if (Object.ReferenceEquals(other, this)) //Not mandatory
                return true;
    
            return String.Equals(this.foo, other.foo);
        }
        public int CompareTo(Foo other)
        {
            if (Object.ReferenceEquals(other, null))
                return 1;
            if (Object.ReferenceEquals(other, this)) //Not mandatory
                return 0;
    
            return String.Compare(this.bar, other.bar);
        }
        public override bool Equals(object obj)
        {
            return this.Equals(obj as Foo);
        }
        public override int GetHashCode()
        {
            return this.bar == null ? 0 : this.bar.GetHashCode();
        }
    }
    

    A good tutorial on this: http://winsharp93.wordpress.com/2009/06/28/implementing-icomparablet-iequatablet-and-the-equality-members/

    Since you know the interfaces IComparable, IEquatable needs to be implemented you can tell if two instances of yourClass are comparable by using this (example):

    if (yourClass is IEquatable<T> && yourClass2 is IEquatable<T> && yourClass is IComparable<T> && yourClass2 is IComparable<T>) //T is the same type
    {
    yourClass <= yourClass2;
    }