OdeToCode IC Logo

More Fun With Generics: Action, Converter, Comparison

Sunday, July 11, 2004
As a follow up to yesterday’s blog about the Predicate<T> delegate, I wanted to try out the three additional delegate types in the generics area.

First, a new type to work with:

class Person
{
   public Person(string name, DateTime birthday)
   {
       this.name = name;
       this.birthday = birthday;
   }
 
   public string Name
   {
       get { return this.name; }
       set { this.name = value; }
   }
 
   public DateTime Birthday
   {
       get { return this.birthday; }
       set { this.birthday = value; }
   }
 
   string name;
   DateTime birthday;
}

The Comparison<T> delegate represents a method used to compare two types. If you have ever needed to define an entirely new type deriving from IComparer just to tell Array.Sort how to compare two objects, you’ll appreciate the brevity in the following sample.

List<Person> list = new List<Person>();
 
list.Add(new Person("Alex", DateTime.Now.AddYears(-30)));
list.Add(new Person("Neal", DateTime.Now.AddYears(-20)));
list.Add(new Person("Geddy", DateTime.Now.AddYears(-25)));
 
list.Sort(
      delegate(Person x, Person y)
      {
        return Comparer<DateTime>.Default.Compare(x.Birthday, y.Birthday);
      }
 );

Next is the Converter<T,U> delegate. Use this delegate to convert each object of type T in a collection to type U.

List<int> yearList;
yearList = list.ConvertAll<int>(
        delegate(Person p)
        {  
            return p.Birthday.Year;
        }
   );

Finally, there is the Action<T> delegate. Use this delegate to perform an action with each object of the collection.

yearList.ForEach(
        delegate(int year) { Console.WriteLine(year); }
    );

I am generally grouchy about any new language feature until I can write some code and figure out its purpose in life. Generics I knew would be a hit, and after writing this code I’m starting to warm up to anonymous delegates.