Aug 272008
 

I decided to come out of my cave and look around 3.5 a bit. I haven’t read much about extension methods, but find them quite useful. They are nothing more than a syntactically superior static helper method. Let’s look at a quick example so I can get back to coming up with more excuses to use them everywhere.


I like to batch my database calls as much as possible to avoid repeated opening/closing of connections, etc. To do this, I pass a bunch of ID values into a stored procedure as a comma-separated string. In the stored proc, I break the string apart with everyone’s favorite table-valued function fn_MakeTable() to make a table of IDs. Then I can JOIN, UPDATE, or INSERT as needed.


So let’s say I have a collection of Orders which I can easily convert to an array of OrderID integers with LINQ. My new best friend to create a comma-separated string of OrderIDs is the following.



    1 using System;


    2 using System.Configuration;


    3 


    4 namespace Common


    5 {


    6     public static class ArrayHelper


    7     {


    8         public static string ToCsv<T>(this T[] array)


    9         {


   10             Converter<T, string> converter = (t) =>


   11                 {


   12                     return t.ToString();


   13                 };


   14             return ToCsv(array, converter);


   15         }


   16 


   17         public static string ToCsv<T>(this T[] array, Converter<T, string> converter)


   18         {


   19             CommaDelimitedStringCollection csv = new CommaDelimitedStringCollection();


   20             foreach (T t in array)


   21             {


   22                 csv.Add(converter(t));


   23             }


   24             return csv.ToString();


   25         }


   26     }


   27 }


 


You’ll see that I have two ToCsv() methods. The first takes a generic array using the this keyword and uses .ToString() as a default converter to string. The second method requires you to additionally pass in a converter to convert the object of type T to a string. Take those converted strings, add them to a CommaDelimitedStringCollection and .ToString() that collection to a full CSV string of integer values.


There are two ways to call these extension methods. The first is the more familiar way. Since they are really nothing more than static helper methods, call them just like any other:



   14             int[] array = { 123, 456 };


   15             string csv = Common.ArrayHelper.ToCsv(array);


 


The second is the more elegant and more intuitive way. Call it as if it was built into the Framework:



   14             int[] array = { 123, 456 };


   15             string csv = array.ToCsv();


 


You may be wondering, what if I write a method that matches the signature of a built-in method like .ToString(). Well, the built-in methods take precedence over extension methods, so array.ToString() will still appear as System.Int32[]. To get your new meaning of .ToString(), you just have to call it in the static helper method way detailed above.


For a generic array of T, you will likely want to provide your own Converter if T’s .ToString() method does not display the information you want to show in the CSV string. Below is a lame example of a converter. It takes the int value, converts it to the char value.



   21             Converter<int, string> converter = (i) =>


   22             {


   23                 return ((char)i).ToString();


   24             };


   25             string csv = array.ToCsv(converter);


 


I think something so simple, and definitely re-usable, would benefit any developer.

 Posted by at 2:07 am

 Leave a Reply

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>

(required)

(required)