Tuesday, January 13, 2009

How to use the IComparable and IComparer interfaces in Visual C#

How to use the IComparable and IComparer interfaces in Visual C#

This step-by-step article describes the use of two interfaces: IComparer and IComparable. These interfaces are discussed in the same article for two reasons. These interfaces are frequently used together, and although the interfaces are similar (and have similar names), they serve different purposes.

If you have an array of types (such as string or integer) that already support IComparer, you can sort that array without providing any explicit reference to IComparer. In that case, the elements of the array are cast to the default implementation of IComparer (Comparer.Default) for you. However, if you want to provide sorting or comparison capability for your custom objects, you must implement either or both of these interfaces.

The following .NET Framework Class Library namespace is referenced in this article: System.Collections

IComparable:
The role of IComparable is to provide a method of comparing two objects of a particular type. This is necessary if you want to provide any ordering capability for your object. Think of IComparable as providing a default sort order for your objects. For example, if you have an array of objects of your type, and you call the Sort method on that array, IComparable provides the comparison of objects during the sort. When you implement the IComparable interface, you must implement the CompareTo method, as follows:

// Implement IComparable CompareTo method - provide default sort order.
int IComparable.CompareTo(object obj)
{
car c=(car)obj; return String.Compare(this.make,c.make);
}

The comparison in the method is different depending on the data type of the value that is being compared. String.Compare is used in this example because the property that is chosen for the comparison is a string.

IComparer :
The role of IComparer is to provide additional comparison mechanisms. For example, you may want to provide ordering of your class on several fields or properties, ascending and descending order on the same field, or both.

Using IComparer is a two-step process. First, declare a class that implements IComparer, and then implement the Compare method:

private class sortYearAscendingHelper : IComparer
{
int IComparer.Compare(object a, object b)
{
car c1=(car)a;
car c2=(car)b;
if (c1.year > c2.year)
return 1;
if (c1.year < c2.year)
return -1;
else
return 0;
}
}

Note that the IComparer.Compare method requires a tertiary comparison. 1, 0, or -1 is returned depending on whether one value is greater than, equal to, or less than the other. The sort order (ascending or descending) can be changed by switching the logical operators in this method.

The second step is to declare a method that returns an instance of your IComparer object:
public static IComparer sortYearAscending()
{
return (IComparer) new sortYearAscendingHelper();
}
In this example, the object is used as the second argument when you call the overloaded Array.Sort method that accepts IComparer. The use of IComparer is not limited to arrays. It is accepted as an argument in a number of different collection and control classes.
See more : http://support.microsoft.com/kb/320727

No comments: