Click here to Skip to main content
15,565,894 members
Articles / Programming Languages / C#
Technical Blog
Posted 25 Feb 2010

Tagged as

Stats

13.7K views
3 bookmarked

C# 3.0 Method Extenders

Rate me:
Please Sign up or sign in to vote.
4.00/5 (2 votes)
25 Feb 2010CPOL3 min read
This small post will show you why you want method extenders, how to use them, and the different versions of .NET you will need to deploy.

“Method Extenders” is one of the most useful features introduced in the third version of .NET, which allows us to extend the features of a pre-built class. This small post will show you why you want them, how to use them, and the different versions of .NET you will need to deploy.

Why You Want Extension Methods? Just an Example

Imagine a collection of the type HashTable or Dictionary. It is sometimes convenient to retrieve ANY element of the collection. You don't want the first, you don't want the last (it would be non-sense talking about order in a hash table). You don't want any element in special, just one. The default HashTable or Dictionary collections don't have a GetAnyElement() method, so you would typically iterate through the collection getting the first element you find.

If this operation is done frequently over your code, and you are a clever developer, you won't be duplicating the same piece of code all around, and you will end up with some sort of static code like this:

C#
public static string GetAnyValueOfDictionary(
            Dictionary<string, string> pDictionary)
{
     foreach (string value in pDictionary.Values)
     return value;
     return "";
}

This is nice, but… wouldn't it be MUCH nicer if that method was shown as an instance method (automatically recognized by the IntelliSense) instead of a static one inside a different class?

That is what extension methods give you. Pretty much like ExtenderProviders do at design time, adding properties to controls, ExtensionMethods tell the environment that the GetAnyValue() method is in fact a part of the specific Dictionary instance, so the invocation to the method is through each instance, not through an additional class.

The following is the old way of doing this stuff. Create a static class with some utility methods, and invoke them:

C#
// Old fashioned
Dictionary<string, string> myDictionary = new Dictionary<string, string>();
string anyValue = DictionaryUtils.GetAnyValueOfDictionary(myDictionary);

This forces you to remember that there’s a DictionaryUtils class holding that code. Not anymore… This is the new way:

C#
// Extension Methods
Dictionary<string, string> myDictionary = new Dictionary<string, string>();
string anyValue = myDictionary.GetAnyValue();

Fancy, uh?

What Do I Need to Use Them?

Theoretically, Extension Methods were introduced in .NET 3.0. However, if you try to use them directly, your compiler will say that needs a reference to System.Core.Dll. If you add that reference, you will realize that in fact is a .NET 3.5 DLL. So, here you can follow two different paths:

  1. Add a reference to System.Core.Dll, deploy your application as .NET 3.5, and jump to the next chapter
  2. If deploying your application as .NET 3.5 is not an option, you can always add the following code snippet:
C#
namespace System.Runtime.CompilerServices
{
    public class ExtensionAttribute : Attribute { }
}

This will allow the compiler to work with Extension Methods even in a .NET 2.0 application, as this blog post explains deeply.

How to Write Them?

Now you are ready to write your own extenders. Let’s see the example code for the GetAnyValue extension method:

C#
public static string GetAnyValue(this Dictionary<string, string> source)
       {
           foreach (string key in source.Values)
               return key;
           return "";
       }

As you can see, Method Extenders are written as static methods (inside a static class). Of course, you need a reference to the calling instance object, that’s why the infrequent word “this” appears in the parameters declaration.

The Type you specify on the right of the “this” keyword will state the kind of objects this method extends. Once you have the code, just add a “using” sentence (to the namespace you used for your “extenders” class) in every source file where you want to use them. Et voilá! Method extended… Easy as that:

image

Of course, you can combine this with Generics (using the <T> generic type), to make things even more functional.

Another Useful Example: A WordCount Method for the String Type

In this MSDN page, you can find another useful example: a WordCount method for the “string” type.

C#
public static int WordCount(this string str)
{
return str.Split(new char[] { ' ', '.', '?' },
	StringSplitOptions.RemoveEmptyEntries).Length;
}

Of course, you can put your own split char preferences there, but it’s indeed a handy method, isn't it?

Take care!

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer (Senior)
Spain Spain
Inaki Ayucar is a Microsoft MVP in DirectX/XNA, and a software engineer involved in development since his first Spectrum 48k, in the year 1987. He is the founder and chief developer of The Simax Project (www.simaxvirt.com) and is very interested in DirectX/XNA, physics, game development, simulation, C++ and C#.

His blog is: http://graphicdna.blogspot.com

To contact Inaki: iayucar@simax.es

Comments and Discussions

 
General[My vote of 2] Your example Pin
tonyt25-Feb-10 8:51
tonyt25-Feb-10 8:51 
GeneralRe: [My vote of 2] Your example Pin
Inaki Ayucar25-Feb-10 9:12
Inaki Ayucar25-Feb-10 9:12 
I really appreciate your comment, but I´m sorry, I do not agree.

Mostly because the "FirstOrDefault" extender is only available in .Net 3.5 applications that reference System.Core.Dll. If you cannot (or don´t want to) deploy your application as 3.5, the example is absolutetly valid.

In fact, I included an specific chapter in the post to cover those cases (using extenders in .Net 2.0 and 3.0 applications, which is perfectly possible). Keep in mind that many people try to keep their applications with as low requirements as possible. However it was just an example... the real point of the post was extenders, not that one in particular.

Regarding the "generics" issue, I do mention that in the post too ("Of course, you can combine this with Generics (using the <t> generic type), to make things even more functional"), but thanks for the example anyway.

Best regards,

Inaki.
Inaki Ayucar
http://graphicdna.blogspot.com

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.