CHAPTER 8 WORKING WITH INTERFACES
34 Viper
234 Mary
Specifying Multiple Sort Orders with IComparer
In this version of the Car type, you used the car’s ID as the base for the sort order. Another design might
have used the pet name of the car as the basis for the sorting algorithm (to list cars alphabetically). Now,
what if you wanted to build a Car that could be sorted by ID as well as by pet name? If this is the type of
behavior you are interested in, you need to make friends with another standard interface named
IComparer, defined within the System.Collections namespace as follows:
// A general way to compare two objects.
interface IComparer
{
int Compare(object o1, object o2);
}
Note The generic version of this interface (IComparer) provides a more type-safe manner to handle
comparisons between objects. You’ll examine generics in Chapter 9.
Unlike the IComparable interface, IComparer is typically not implemented on the type you are trying
to sort (i.e., the Car). Rather, you implement this interface on any number of helper classes, one for each
sort order (pet name, car ID, etc.). Currently, the Car type already knows how to compare itself against
other cars based on the internal car ID. Therefore, allowing the object user to sort an array of Car objects
by pet name will require an additional helper class that implements IComparer. Here’s the code (be sure
to import the System.Collections namespace in the code file):
// This helper class is used to sort an array of Cars by pet name.
public class PetNameComparer : IComparer
{
// Test the pet name of each object.
int IComparer.Compare(object o1, object o2)
{
Car t1 = o1 as Car;
Car t2 = o2 as Car;
if(t1 != null && t2 != null)
return String.Compare(t1.PetName, t2.PetName);
else
throw new ArgumentException("Parameter is not a Car!");
}
}
The object user code is able to make use of this helper class. System.Array has a number of
overloaded Sort() methods, one that just happens to take an object implementing IComparer.
316