IEnumerator and IComparer are two classes that unlock some of the most powerful features of collections. The proper term for IEnumerator and IComparer is interface, a term I will describe shortly. Every class that implements the IEnumerator interface is capable of retrieving a list of pointers for all the items in a collection, and you can use this list to iterate through the items in a collection. Every collection has a built-in enumerator, and you can retrieve it by calling its GetEnumerator method. Every class that implements the IComparer interface exposes the Compare method, which tells the compiler how to compare two objects of the same type. After the compiler knows how to compare the objects, it can sort a collection of objects with the same type.
The IComparer interface consists of a function that compares two items and returns a value indicating their order (which one is the smaller item or whether they’re equal). The Framework can’t compare objects of all types; it knows only how to compare the base types. It doesn’t even know how to compare built-in objects such as two rectangles or two color objects. If you have a collection of colors, you might want to sort them according to their luminance, saturation, brightness, and so on. Rectangles can be sorted according to their area or perimeter. The Framework can’t make any assumptions as to how you might wish to sort your collection and, of course, it doesn’t expose members to sort a collection in all possible ways. Instead, it gives you the option to specify a function that compares two colors (or two objects of any other type, for that matter) and uses this function to sort the collection. The same function is used by the BinarySearch method to locate an item in a sorted collection. In effect, the IComparer interface consists of a single function that knows how to compare two specific custom objects.
So, what is an interface? An interface is another term in object-oriented programming that describes a very simple technique. When we write the code for a class, we might not know how to implement a few operations, but we do know that they’ll have to be implemented later. We insert a placeholder for these operations (one or more function declarations) and expect that the application that uses the class will provide the actual implementation of these functions. All collections expose a Sort method,which sorts the items in the collection by comparing them to one another. To do so, the Sort method calls a function that compares two items and returns a value indicating their relative order. Custom objects must provide their own comparison function — or more than a single function, if you want to sort them in multiple ways. Because you can’t edit the collection’s Sort method code, you must supply your comparison function through a mechanism that the class can understand. This is what the IComparer interface is all about.