How to declare natural ordering by implementing the generic IComparable interface in C# .NET
October 18, 2017 Leave a comment
Primitive types such as integers can be ordered naturally in some way. Numeric and alphabetical ordering comes in handy with numbers and strings. However, there’s no natural ordering for your own custom objects with a number of properties.
Consider the following Triangle class:
public class Triangle { public double BaseSide { get; set; } public double Height { get; set; } public double Area { get { return (BaseSide * Height) / 2; } } }
Imagine that you want to be able to declare that one triangle is larger or smaller than another one in a natural way. One way to declare natural comparison is by implementing the generic IComparable interface which comes with one method, CompareTo, which returns an integer. The method should return 0 if the compared instances are equal. It should return an integer larger than 0 if “this” current instance is larger/higher/longer etc. than the instance it is compared to. The reverse is true if “this” instance is ranked behind the other instance.
Here comes an example for the Triangle class:
public class Triangle : IComparable<Triangle> { public double BaseSide { get; set; } public double Height { get; set; } public double Area { get { return BaseSide * Height; } } public int CompareTo(Triangle other) { if (other == null) return 1; if (Area > other.Area) return 1; return -1; } }
…and here’s how you can call the CompareTo method:
Triangle tOne = new Triangle() { BaseSide = 4, Height = 2 }; Triangle tTwo = new Triangle() { BaseSide = 5, Height = 3 }; if (tOne.CompareTo(tTwo) > 0) { Console.WriteLine("tOne is larger than tTwo: {0} vs. {1}", tOne.Area, tTwo.Area); } else { Console.WriteLine("tOne is smaller than tTwo: {0} vs. {1}", tOne.Area, tTwo.Area); }
As tOne is smaller than tTwo the control flow will take the “else” path.
As the CompareTo method is by default implemented on numeric types – and strings – we can have a simpler implementation of the EqualTo method:
public int CompareTo(Triangle other) { return Area.CompareTo(other.Area); }
We’ll soon look at a related interface, the generic IComparer of T which provides for more sophisticated ordering logic.
View all various C# language feature related posts here.