Monday, August 01, 2005

Comparing the Un-Comparable

A project I was working on required variables of type struct to be stored in an ArrayList. The storing-in-ArrayList part was very easy because any variable that derives from class 'Object' can be stored in a Collection/ArrayList. However, a problem surfaced when I wanted to call the 'Sort' method on the ArrayList to sort all the stored values. Remember, variables of a user-defined type cannot be sorted since there is no pre-defined mechanism to compare 2 variables of that user-defined type. So, if you are ever faced with a similar situation, rest-assured, .NET would never leave you out in the cold.

You would need to implement the IComparable interface in your definition, and define the mechanism for comparison of 2 instances of that type. Visual Studio .NET makes it more easy; as soon as you type the declarator statement for the struct type (preceding the opening de-limiter operator), a tool-tip text would appear saying 'Press TAB to implement stubs for interface System.iComparable'. Press the TAB key and behold; VS.NET would automatically add a 'CompareTo' method that accepts an object as argument and returns an integer. The 'CompareTo' method is where you would define your comparison mechanism, which would subsequently be called when a comparison between variables of that type is to be made. In most cases, the result of a comparison operation is boolean (0 or 1); however, in case you need to know if instance of one variable is greater than-, less than-, or equal to- the another instance, you need three flags or values (-1, 0, and 1); hence the int return type in the 'CompareTo' method. To elaborate, I am including a simple example below:


public struct Length : IComparable
{
public int Feet;
public int Inches;

#region IComparable Members

public int CompareTo(object obj)
{
if (!(obj is Length))
throw new Exception("Cannot compare.");

Length l = new Length();
l = (Length)obj;

if (Feet == l.Feet && Inches == l.Inches)
return 0;
else if (Feet > l.Feet)
return 1;
else
return -1;
}

#endregion
}

0 comments: