11
Oct
2005

Automatic comparison operator overloading in C#

Abhinaba has blogged on the painful C# operator overloading experience.

The basic problem that is if you want to overload one, you soon end up many of the tests including == != < <= > >= Equals, Compare and probably CompareTo via IComparable when it turns out one function can provide everything needed in general use.

Apparently Ruby already has this with the <=> operator, sometimes known as a SpaceShipOperator.

This got me thinking and I knocked up the following little class:

using System;

///
/// AutoOperators provides a base class where all the standard operators are overridden and
/// wired up via the subclass's implementation of IComparable.CompareTo.
///
/// damien@envytech.co.uk, no warranty implied or expressed

public abstract class AutoOperators : IComparable
{
  #region Operator overloads

  public static bool operator < (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) < 0;
  }
  public static bool operator > (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) > 0;
  }
  public static bool operator == (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) == 0;
  }
  public static bool operator != (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) != 0;
  }
  public static bool operator <= (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) <= 0;
  }
  public static bool operator >= (AutoOperators obj1, AutoOperators obj2) {
    return Compare(obj1, obj2) >= 0;
  }

  #endregion

  #region Static methods

  public static int Compare(AutoOperators obj1, AutoOperators obj2) {
    if (Object.ReferenceEquals(obj1, obj2)) return 0;
    if ((object)obj1 == null) return -1;
    if ((object)obj2 == null) return 1;
    return obj1.CompareTo(obj2);
  }

  #endregion

  #region Methods

  public abstract int CompareTo(object obj);
  public abstract override int GetHashCode();

  public override bool Equals(object obj) {
    if (!(obj is AutoOperators)) return false;
    return this == (AutoOperators) obj;
  }

  #endregion
}

And then to use it simply inherit from it and implement GetHashCode and CompareTo, e.g.

using System;

///
/// Sample class demonstrating use of AutoOperators.
///

public class SampleClass : AutoOperators
{
  #region Instance variables

  private int testValue = 0;

  #endregion

  #region Construction

  public SampleClass(int initialTestValue) {
    testValue = initialTestValue;
  }

  #endregion

  #region "Properties"

  public int TestValue {
    get { return testValue; }
    set { testValue = value; }
  }

  #endregion

  #region Methods

  public override int CompareTo(object obj) {
    if (obj is SampleClass)
       return TestValue.CompareTo(((SampleClass) obj).TestValue);
    else
       return -1;
  }

  public override int GetHashCode() {
    return TestValue.GetHashCode();
  }

  #endregion
}

As with all code, determine the suitability of this solution to your own needs - that responsibility is yours. As with all code here it comes without warranty, expressed, implied or otherwise alluded to.

I'd recommend checking out the performance, CLS compliance regarding operators and the addition of any extra operators you use all the time.

[)amien

Share with others
  • Digg
  • description
  • StumbleUpon
  • description
  • Reddit
  • del.icio.us
  • Google
  • Live
  • Technorati

0 responses to “Automatic comparison operator overloading in C#”


  1. No comments

Leave a reply