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.


Comments
Andy Sunday, July 11, 2004
Correct me if I'm wrong, I just started picking up C#. It looks like they took the best of the STL and ported it to C# and called it &quot;generics&quot;. Are Generics true templates like Generics in C++ ? Or are they ports so you only get the most commonly used ones from the STL ?
Scott Allen Sunday, July 11, 2004
They are pretty similar in concept at least, though the implementation differs pretty drastically (compile time versus run time).
<br>See:http://blogs.msdn.com/csharpfaq/archive/2004/03/12/88913.aspx
<br>
<br>The STL is pretty extensive, you won't find all those features in C#, but generics also lack some of the complexity of C++ templates.
Andy Sunday, July 11, 2004
Thanks for the link. I'm off to read it now. I use templates a lot in C++ and the ones in the STL too. That's why I ask. The examples you posted are much easier to read though than when I first started using templates in C++ I would try and get intellisense and it would end up being 150 symbols long. Legibility is something C++ templates really lack. Once you get used to them it's fine but C# looks to have drastically increased the readability factor.
Andy Sunday, July 11, 2004
Reading that link and it's comments I came across this too:
<br>http://www.artima.com/intv/generics.html
<br>
<br>So far I'm not sure (from what I have read only) that I like generics much in C#. They are better than Java's for sure but here are my reasons.
<br>
<br>Reason numbers:
<br>1.) It's runtime checked. That means it breaks at runtime if something goes wrong. Bad juju. I want to know when I compile that I am safe doing &quot;X&quot; operation.
<br>2.) It's strongly typed. Weak/loose typing ability in a strongly typed language is what makes templates really cool.
<br>3.) It's runtime overhead. Remember when you posted the example of Duff's device. Templates do the same thing for your code but on steroids . They unwind at precompile time into separate chunks of code and then are separately compiled. The compile time can be slow, the disk memory space used is a bit larger just like unrolling loops. In the end though you get much faster and more easily extended code. If it's checked JIT at runtime you loose that whole huge reason for using templates in the first place.
<br>4.) It doesn't seem really generic in the sense I'm used to. The strong typing makes it so that you could just put the same code into the interface itself and then use that classes interface with no generics and accomplish the exact same thing by just using the interface.
<br>
<br>Things so far it has going for it:
<br>1.) Way, way, way more readable.
<br>
<br>I'm not passing any kind of judgment at all, I need to do a lot lot more reading and testing of it before I can say one way or the other. These are just my initial impressions after reading all that stuff. The interview with Eckel and Hejlsberg was especially usefull reading.
Comments are now closed.
by K. Scott Allen K.Scott Allen
My Pluralsight Courses
The Podcast!