Extension Methods
[Blog Map] [Table of Contents] [Next Topic]
This blog is inactive.
New blog: EricWhite.com/blogBlog TOCNote: This article is a topic in a much larger tutorial on writing pure functional code in C#. Extension methods are only one of the pieces in a much larger puzzle. Functional programming in C# allows us to write shorter programs that perform better, and are much more robust. Query Composition using Functional Programming Techniques explains extension methods in their proper context.
Extension methods are special methods that, while they are not part of a data type, you can call them as though they were part of the data type. Extension methods are a feature of C# 3.0.
Writing Extension Methods
To write an extension method, you do the following:
· Define a public static class.
· Define a public static method in the class where the first argument is the data type for which you want the extension method.
· Use the this keyword on the first argument to your public static method. The this keyword denotes the method as an extension method.
This special syntax is actually simply a natural extension of what you do normally when you want to make a utility method for a class that you don't want to (or can't) extend. A common pattern when you want to write a utility method is to define a static method that takes an instance of the class as the first parameter. This is exactly what an extension method is - the only difference is that you can then write a call to the method as though it were part of the class, and the compiler will find and bind to the extension method.
Note that the following class does not define a PrintIt method:
public class MyClass
{
public int IntField;
public MyClass(int arg)
{
IntField = arg;
}
}
This static class defines an extension method for the MyClass class:
public static class MyClassExtension
{
public static void PrintIt(this MyClass arg)
{
Console.WriteLine("IntField:{0}", arg.IntField);
}
}
You can now call the PrintIt method as though it were part of the class.
MyClass mc = new MyClass(10);
mc.PrintIt();
When you run this code, it outputs:
IntField:10
But the really cool thing is that you can write extension methods for a type that in and of itself, can't contain methods. The most important example of this is that you can write extension methods for interfaces. You could also write an extension method for an abstract class.
You can define extension methods for parameterized types as well as non-parameterized types. The standard query operators are almost all extension methods that are defined on IEnumerable<T>.
Note that you can define your own extension methods for IEnumerable<T>. When there isn't a standard query operator that does exactly what you want, you can write your own extension method. This is a powerful technique that adds expressiveness to your code.
When you are writing pure functional code, extension methods are important. There are times that writing extension methods on IEnumerable<T> is the way that you want do things. We'll be using this technique sometimes when writing FP code.
Extension Methods are Vital for LINQ
Extension methods are an integral part of LINQ. Consider the following code that contains a LINQ query expression:
int[] source = new[] { 3, 6, 4, 8, 9, 5, 3, 1, 7, 0 };
IEnumerable<int> query =
from i in source
where i >= 5
select i * 2;
foreach (var i in query)
Console.WriteLine(i);
This code is functionally identical to this:
int[] source = new[] { 3, 6, 4, 8, 9, 5, 3, 1, 7, 0 };
IEnumerable<int> query =
source.Where(i => i >= 5)
.Select(i => i * 2);
foreach (var i in query)
Console.WriteLine(i);
In fact, you can see that there is a direct translation from the query expression to the same query that is expressed in method notation. I believe that in early versions of the C# 3.0 compiler, this translation was implemented almost like a macro. But in any case, queries that are implemented via method syntax rely, of course, on the extension methods that are included with the .NET framework, and hence query expressions also rely on them. It is the ability to write extension methods for generic interfaces that enables queries.
[Blog Map] [Table of Contents] [Next Topic]
Comments
Anonymous
July 09, 2007
In Debugging of and error handling for synchronous Commands I explained why you can't handle exceptionsAnonymous
June 05, 2008
The comment has been removedAnonymous
June 06, 2008
@DKE, Your point is interesting. However, with multiple inheritance (MI) in C++, there is a different abstraction - MI means that a class has an 'is a' relationship to both of its parent classes. The encapsulation semantics are different - a MI derived class has access to private members of both base classes. In contrast, extension methods don't break encapusulation - you can't access private members. There is another concept in object oriented design, which is the idea of an extension class - you can extend an existing class with additional storage and methods. (Think: add a object as an annotation to another object.) There are no mainstream languages that implement this idea. I've only seen proofs-of-concept prototype languages that do this. Extension methods are a partial implementation of 'extension classes'. When you have a general purpose mechanism such as annotations in LINQ to XML, then annotations+extension methods effectively equals extension classes, although the syntax isn't perfectly clean (but it's not bad). I've also seen the idea of extension properties batted around. But there are serious performance issues unless the properties are added as an annotation of some sort. So, my point of view is: it isn't really an implementation of an 'is a' relationship. It is an approach to extending classes and interfaces, - a partial implementation of 'extension classes'. Interestingly, I have never encountered a class design problem where I absolutely needed to use multiple implementation inheritance. So far, there have always been other ways to look at it, and other patterns to use that solve the designated problem without saying that one particular class has an 'is a' relationship to two parent classes. Multiple interface inheritance is another matter - important for a variety of reasons. -EricAnonymous
July 28, 2008
[Table of Contents] [Next Topic] In order to learn functional programming and a more declarative styleAnonymous
July 31, 2008
You say "There are times that writing extension methods on IEnumerable<T> is the way that you want do things." But I don't see where. Ther are so many already. I sure would like an example. Could be one later in the series... I haven't been through the whole thing.Anonymous
July 31, 2008
@Kirk.B, There are two situations where I've used extension methods to good effect:
- Sometimes you want to add functionality to a sealed class. Here are two examples: http://blogs.msdn.com/ericwhite/archive/2008/07/09/open-xml-sdk-and-linq-to-xml.aspx http://blogs.msdn.com/ericwhite/archive/2006/08/31/734383.aspx
- There is, for instance, grouping functionality that is difficult to get out of the standard extension methods: http://blogs.msdn.com/ericwhite/archive/2008/04/21/the-groupadjacent-extension-method.aspx Extension methods are one of the syntactical constructs that allow us to gain composability. Composability allows us to embed / add / remove / inject / surround / refactor code with a cleaner syntax, and avoid brittleness at the same time. Does this make sense? -Eric
Anonymous
August 04, 2008
Eric, Thanks for the links. I especially appreciate the GroupAdjacent extension method.Anonymous
March 14, 2013
you can visit this post for extension methods which wrote a friend of mine codingsack.com/.../some-use-full-string-extension-methods-c-sharp-dot-net-by-sm-abdullah-.html