Subscribe

RSS Feed (xml)

How to Implement IComparable in C#

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.

No comments:

Post a Comment

Archives

LocalsAdda.com-Variety In Web World

Fun Mail - Fun in the Mail