Thursday, November 23, 2006

Following my last article on IComparable vs IComparer interfaces I now present a common pattern that I have found to be very effective in terms of code usability.

In order to make working with IComparer implementing classes more natural and intelisense friendly I usually create the inner classes of the main class and expose the objects as as static properties or methods. The following example demonstrates:

public class Person
{
  int age;
  string name;
  public static IComparer<Person> GetPersonAgeComparer()
  {
    return new PersonAgeComparer();
  }
  public static IComparer<Person> GetPersonNameComparer()
  {
    return new PersonNameComparer();
  }
  private class PersonAgeComparer : IComparer<Person>
  {
    #region IComparer<Person> Members
    public int Compare(Person x, Person y)
    {
      return x.age.CompareTo(y.age);
    }
    #endregion
  }
  private class PersonNameComparer : IComparer<Person>
  {
    #region IComparer<Person> Members
    public int Compare(Person x, Person y)
    {
      return x.name.CompareTo(y.name);
    }
    #endregion
  }
}

Now when you need to sort a collection of Person objects you just get the right IComparer from the Person's static Get*Comparer methods. Notice that the IComparer classes are defined as private so the only way to create them is through the factory - like static method. Making the classes private is nice a way to prevent Intelisense from unnecessary displaying them when what we really need is the concrete object. Notice the use of generic interface, which is new to the .NET Framework 2.0. You could also use the partial classes feature to put the comparers in a separate file if necessary.

kick it on DotNetKicks.com