Implementing IComparable


If you want to sort a collection that contains user-defined objects (or if you want to store those objects in a collection such as SortedList, which maintains its elements in sorted order), then the collection must know how to compare those objects. One way to do this is for the object being stored to implement the IComparable interface. The IComparable interface comes in two forms: generic and non-generic. Each is examined here.

Implementing IComparable for Non-Generic Collections

If you want to sort objects that are stored in a non-generic collection, then you will implement the non-generic version of IComparable. It defines only one method, CompareTo( ), which determines how comparisons are performed. The general form of CompareTo( ) is shown here:

 int Compare To(object obj)

Compare To( ) compares the invoking object to obj. To sort in ascending order, your implementation must return zero if the objects are equal, a positive value if the invoking object is greater than obj, and a negative value if the invoking object is less than obj. You can sort in descending order by reversing the outcome of the comparison. The method can throw an ArgumentException if the type of obj is not compatible for comparison with the invoking object.

Here is an example that shows how to implement IComparable. It adds IComparable to the Inventory class developed in the preceding section. By implementing IComparable, it allows a collection of Inventory objects to be sorted, as the program illustrates.

 // Implement IComparable. using System; using System.Collections; // Implement the non-generic IComparable interface. class Inventory : IComparable {   string name;   double cost;   int onhand;   public Inventory(string n, double c, int h) {     name = n;     cost = c;     onhand = h;   }   public override string ToString() {     return       String.Format("{0,-10}Cost: {1,6:C}  On hand: {2}",                     name, cost, onhand);   }   // Implement the IComparable interface.   public int Compare To(object obj) {     Inventory b;     b = (Inventory) obj;     return name.CompareTo(b.name);   } } class IComparableDemo {   public static void Main() {     ArrayList inv = new ArrayList();     // Add elements to the list     inv.Add(new Inventory("Pliers", 5.95, 3));     inv.Add(new Inventory("Wrenches", 8.29, 2));     inv.Add(new Inventory("Hammers", 3.50, 4));     inv.Add(new Inventory("Drills", 19.88, 8));     Console.WriteLine("Inventory list before sorting:");     foreach(Inventory i in inv) {       Console.WriteLine("   " + i);     }     Console.WriteLine();     // Sort the list.     inv.Sort();     Console.WriteLine("Inventory list after sorting:");     foreach(Inventory i in inv) {       Console.WriteLine("   " + i);     }   } }

Here is the output. Notice that after the call to Sort( ), the inventory is sorted by name.

 Inventory list before sorting:    Pliers    Cost:  $5.95  On hand: 3    Wrenches  Cost:  $8.29  On hand: 2    Hammers   Cost:  $3.50  On hand: 4    Drills    Cost: $19.88  On hand: 8 Inventory list after sorting:    Drills    Cost: $19.88  On hand: 8    Hammers   Cost:  $3.50  On hand: 4    Pliers    Cost:  $5.95  On hand: 3    Wrenches  Cost:  $8.29  On hand: 2

Implementing IComparable<T> for Generic Collections

If you want to sort objects that are stored in a generic collection, then you will implement IComparable<T>. This version defines the generic form of CompareTo( ) as shown here:

 int CompareTo(T obj)

CompareTo( ) compares the invoking object to obj. Notice that obj is of type T. To sort in ascending order, your implementation must return zero if the objects are equal, a positive value if the invoking object is greater than obj, and a negative value if the invoking object is less than obj. To sort in descending order, reverse the outcome of the comparison. When implementing Icomparable<T>, you will usually pass the type name of the implementing class as a type argument.

The following example reworks the preceding program so that it uses IComparable<T>. Notice that it uses the generic List<T> collection rather than the non-generic ArrayList.

 // Implement IComparable<T>. using System; using System.Collections.Generic; // Implement the generic IComparable<T> interface. class Inventory : IComparable<Inventory> {   string name;   double cost;   int onhand;   public Inventory(string n, double c, int h) {     name = n;     cost = c;     onhand = h;   }   public override string ToString() {     return       String.Format("{0,-10}Cost: {1,6:C}  On hand: {2}",                     name, cost, onhand);   }   // Implement the IComparable<T> interface.   public int CompareTo(Inventory obj) {     return name.CompareTo(obj.name);   } } class GenericIComparableDemo {   public static void Main() {     List<Inventory> inv = new List<Inventory>();     // Add elements to the list     inv.Add(new Inventory("Pliers", 5.95, 3));     inv.Add(new Inventory("Wrenches", 8.29, 2));     inv.Add(new Inventory("Hammers", 3.50, 4));     inv.Add(new Inventory("Drills", 19.88, 8));     Console.WriteLine("Inventory list before sorting:");     foreach(Inventory i in inv) {       Console.WriteLine("   " + i);     }     Console.WriteLine();     // Sort the list.     inv.Sort();     Console.WriteLine("Inventory list after sorting:");     foreach(Inventory i in inv) {       Console.WriteLine("   " + i);     }   } }

This program produces the same output as the previous, non-generic version.




C# 2.0(c) The Complete Reference
C# 2.0: The Complete Reference (Complete Reference Series)
ISBN: 0072262095
EAN: 2147483647
Year: 2006
Pages: 300

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net