Extension Methods


Extension methods make it possible to write a method to a class that doesn’t offer the method at first.

For example, wouldn’t you like to have a Foo() method with the String class? The String class is sealed, so it is not possible to inherit from this class. You can do an extension method, as shown:

  public static class StringExtension {    public static void Foo(this string s)    {       Console.WriteLine("Foo invoked for {0}", s);    } } 

An extension method is declared in a static class. An extension method is defined as a static method where the first parameter defines the type it extends. The Foo() method extends the string class as is defined with the first parameter. For differentiating extension methods from normal static methods, the extension method also requires the this keyword with the first parameter.

Indeed, now it is possible to use the Foo() method with the string type:

  string s = "Hello"; s.Foo(); 

The result shows Foo invoked for Hello in the console, as Hello is the string passed to the Foo() method.

Maybe this looks like breaking object-oriented rules as a new method is defined for a type without changing the type. However, this is not the case. The extension method cannot access private members of the type it extends. Calling an extension method is just a new syntax of invoking a static method. With the string you can get the same result by calling the method Foo() this way:

  string s = "Hello"; StringExtension.Foo(s); 

To invoke the static method, you write the class name followed by the method name. Extension methods are a different way to invoke static methods. You don’t have to supply the name of the class where the static method is defined. Instead, the static method is taken because of the parameter type. You just have to import the namespace that contains the class to get the Foo() extension method in the scope of the String class.

One of the classes that define LINQ extension methods is Sequence in the namespace System.Query. You just have to import the namespace to open the scope of the extension methods of this class. A sample implementation of the Where() extension method is shown here. The first parameter of the Where() method that includes the this keyword is of type IEnumerable<T>. This way the Where method can be used with every type that implements IEnumerable<T>. Just to mention a few examples, arrays and List<T> implement IEnumerable<T>. The second parameter is a Func<T, bool> delegate that references a method that returns a Boolean value and requires a parameter of type T. This predicate is invoked within the implementation to examine if the item from the IEnumerable<T> source should go into the destination collection. If the method is referenced by the delegate, the yield return statement returns the item from the source to the destination.

  public static IEnumerable<T> Where<T>(this IEnumerable<T> source,                                       Func<T, bool> predicate) {    foreach (T item in source)       if (predicate(item))          yield return item; } 

Because Where is implemented as a generic method, it works with any type that is contained in a collection. Any collection implementing IEnumerable<T> is supported.

Let’s review the query to filter and sort the racers once more. Because Where() is an extension method that returns a collection, in the collection result the OrderByDescending() extension method can be invoked that itself returns a collection. This wouldn’t be possible with normal static methods.

 var queryBrazilRacers = racers.Where<Racer>(r => r.Country == "Brazil").                         OrderByDescending<Racer, int>(r => r.Wins)                         Select(r => r);




Professional C# 2005 with .NET 3.0
Professional C# 2005 with .NET 3.0
ISBN: 470124725
EAN: N/A
Year: 2007
Pages: 427

flylib.com © 2008-2017.
If you may any questions please contact us: flylib@qtcs.net