LINQ: Creating your first Extension Method



I thought I would take a second and post how you can create your own Extension Method. An extension method is a specially defined method that acts like a method defined on a type. LINQ operators, like from, where, select, etc are implemented using extension methods. For example, the where clause checks for a Boolean result of a test (ex: City==”London”). 


 


Creating your first extension method


To show this in action, I want to create my own custom extension method. While the method itself may not be incredibly useful, it should hopefully serve as a simple example of how an extension method works.


 


Assignment


Create an extension method to write values out of an IEnumerable type to the console window, or better stated in MasterCard commercial style: Not ever having to write a foreach loop to write something out to the console, priceless.


 


First, let’s look at a simple LINQ query:


string[] aBunchOfWords = {“One”,“Two”, “Hello”, “World”, “Four”, “Five”};


 


var result =   


from s in aBunchOfWords


where s.Length == 5


select s;


 


Given this query, I can write the values out to the console window using the following:


 


foreach (var s in result)


{


  Console.WriteLine(s);


}


 


This prints out:


Hello


World


 


Defining my extension method


Below is an extension method with no return type named Write(). The only difference between an extension method and a normal method is the keyword this defined in the first parameter.  this is basically a pointer to the object that had the method invoked. Note that extension methods must be static.


 


public static class Utils


{


    public static void Write<T>(this IEnumerable<T> source)


    {


        foreach (var item in source)


        {


            Console.WriteLine(item);


        }


    }


 


Using my previous example, I can now use my custom Write extension method as shown below:


 


result.Write();


 


Like regular methods, extension methods can also be overloaded. For example, you can create an overload for the Write method that works on IEnumerable (non-generic) source as shown below.


public static void Write(this IEnumerable source)


{


    foreach (var item in source)


    {


        Console.WriteLine(item);


    }


}


 


Like before, we use the this keyword in the method signature


 


//Fx 1.1 collection


ArrayList ar = new ArrayList();


ar.Add(1);


ar.Add(2);


ar.Add(3);


 


//calls my custom extension method


ar.Write();


 


Result:


1


2


3


 


ObjectDumper


The LINQ Project Tech Preview download also includes a great source code sample called ObjectDumper found at: C:\Program Files\LINQ Preview\Samples\ObjectDumper


 


ObjectDumper is a class library that let’s you pass an object and, using reflection, it will write the elements and fields of the object to the Console Window, including hierarchical data.


 


In this case, I’m going to write another ExtensionMethod that calls ObjectDumper so that I can easily call ObjectDumper on any type using the convenient method call notation.


 


public static class Utils


{


    public static void Write(this object source)


    {


        ObjectDumper.Write(source);


    }


 


    public static void Write(this object source, int depth)


    {


        ObjectDumper.Write(source, depth);


    }


}


 


Here’s what it would look like on the sample I blogged about earlier on why “var” exists:


 


var result =
from s in aBunchOfWords
where s.Length == 5
//Creates a new anonymous type with name/value pairs
select
new {Value=s, Length=s.Length, FirstThreeLetters=s.Substring(0,3)};


 


Result


Value=Hello     Length=5        FirstThreeLetters=Hel


Value=World     Length=5        FirstThreeLetters=Wor


 


 


Printing manually


//Print values 
foreach
(var x in result)
Console.WriteLine(“Value={0}\t Length={1}\t FirstThreeLetter={2}”,
x.Value, x.Length, x.FirstThreeLetters);


 


Printing with my custom extension method


//Print values 
result.ObjectDump();


 


Language Feature Abuse


While extension methods are handy, they can, like other language features be abused. As LINQ becomes more stable, we’re going to need some clear guidance on when and where to use features. We’re at the earliest stage in development, so we don’t have these now, but you can certainly imagine updating class library design guidelines.


 

Comments (4)

  1. Javier Luna says:

    Nice post Daniel,

    I had developed a Business Layer strongly typed on DLinq with Many-to-Many support.

    Simple database struct: Users and Groups as like project sample.

    http://forums.microsoft.com/msdn/ShowPost.aspx?PostID=109996

    Cheers,

    Javier Luna

  2. abhinaba says:

    Extension methods are extremely useful. The other day while trying to write a method that shows fancy names for enumerated types, I was forced to create an extension method and got a bit mad that they are not there in C#2.0.

    See http://blogs.msdn.com/abhinaba/archive/2005/10/21/483337.aspx

    However like overloaded operators they get me a bit suspicious and always make me look up the code of the extension method to ensure that they do what I wanted them to do….

  3. MicrosoftChap says:

    I appreciate the author in explaining his views in a very clear and simple example.

  4. Maulik says:

    How can I use ObjectDumper in my code? I tried to use it and get the "the name ‘ObjectDumper’ doesnot exist in the current context" error. How can I resolve this error?

    My email address is maulikk2004@gmail.com