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.
GitHub has the latest version of AutoOperators
Ruby already has this with the <=> operator, sometimes known as a SpaceShipOperator and this got me thinking resulting in 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.
public abstract class AutoOperators : IComparable {
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;
}
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);
}
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;
}
}
And then to use it simply inherit from it and implement GetHashCode and CompareTo, e.g.
using System;
public class SampleClass : AutoOperators {
private int testValue = 0;
public SampleClass(int initialTestValue) {
testValue = initialTestValue;
}
public int TestValue {
get { return testValue; }
set { testValue = value; }
}
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();
}
}
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
1 responses