Extending The CultureInfo Class Using Extension Methods

In chapter 6 of .NET Internationalization I wrote a section entitled "Extending The CultureInfo Class". I showed how to inherit from the CultureInfo class and fix the Parent and InvariantCulture properties so that they returned the subclass and the subclass behaved correctly (you can download the source code for the CultureInfoEx class here). In this post I show how to achieve the same result using an alternative approach: Extension Methods. There are two goals behind this post: (1) show how to extend the CultureInfo class and (2) illustrate why Extension Methods are worth taking a good hard look at.

Extension Methods are a new feature in the .NET Framework 3.5. They are often overlooked as a necessary part of enabling LINQ (Language Integrated Query) but they are a profoundly useful feature in their own right. To make use of Extension Methods you will need to download LINQ:-

http://msdn2.microsoft.com/en-us/netframework/aa904594.aspx

An extension method is a method that is added to an existing class without having to recompile the original class. The immediate benefit of this feature is that you can extend classes that you do not have the source code to. The CultureInfo class springs to mind. Here’s an example of how to extend the CultureInfo class using extension methods:-


// ExtendingCultureInfo.cs
using System;
using System.Globalization;
using System.Runtime.CompilerServices;

public class ExtendingCultureInfo
{
static void Main(string[] args)
{
CultureInfo cultureInfo = new CultureInfo("en-GB");
Console.Write(cultureInfo.DisplayName + ": ");
// displays "Invoices"
Console.WriteLine(cultureInfo.ToPlural("Invoice"));
}
}

static class CultureInfoExtensions
{
[Extension]
public static string ToPlural(this CultureInfo cultureInfo, string singular)
{
if (cultureInfo.TwoLetterISOLanguageName == "en")
// English
return singular + "s";
else
return singular;
}
}

To compile this example open up a .NET Framework 2.0 command prompt and using the LINQ C# compiler (not the .NET Framework 2.0 compiler) execute the following line:-

csc ExtendingCultureInfo.cs /reference:"C:\Program Files\LINQ Preview\Bin\System.Query.dll"

The CultureInfoExtensions class includes a static method called ToPlural which converts a singular word to a plural word. (The algorithm represented here is simplistic in the extreme and is intended as an example as opposed to a realistic implementation). This static method accepts a CultureInfo parameter which is qualified with the "this" keyword. This parameter is passed by the compiler and is a reference to the object that the method was called on. The existence of this parameter explains why there is no such thing as Extension Properties. Also note that the ToPlural method is decorated with the Extension attribute to mark that the method extends another class. When the new method is used by an object it is referenced in the same way as a built in method without any special syntax required by the extension method.

So why is this so clever ? It is clever for a number of reasons. First, as I have already mentioned you do not need the original source code to extend a class and therefore this is very relevant for all classes that are part of the .NET Framework. Second, you can extend sealed classes and as I am not a big fan of sealed classes this makes me happy. Third, and this is the defining point, you do not need to be in control of the code that creates a new object of the class you want to extend. Think about this: if<

Be the first to rate this post

  • Currently 0/5 Stars.
  • 1
  • 2
  • 3
  • 4
  • 5

Posted by: Guy Smith-Ferrier
Posted on: Monday, March 12, 2007 at 8:41 PM
Categories: Internationalization
Actions: E-mail | Kick it! | DZone it! | del.icio.us
Post Information: Permalink | Comments (2) | Post RSSRSS comment feed

Related posts

Comments

Guy Smith-Ferrier

Tuesday, March 13, 2007 11:41 PM

guy[at]guysmithferrier[dot]com

Lex,

Smile you enjoyed writing that, didn’t you ?

Yes, I remember Class Helpers from Delphi and I agree that it provides similar features. I think it is entirely possibly though that had LINQ not needed this feature then we might never have had it.

Personally, though, I’m delighted. At least it removes some of the barriers of sealed classes.

Guy

Lex Mark

Tuesday, March 13, 2007 11:41 PM

Lex Mark

In fact, Borland/CodeGear’s Delphi for .NET first implemented similar language feature named Class Helper on .NET 1.1. Fine to see Microsoft implements this in .NET 3.5 at last.