Sunday 18 May 2008

Extension Methods - My new best friend*

No that doesn't mean that I'm going to be [ab]using extension methods everywhere - though I suspect that extension methods could become the new singleton. That said I think that I am really starting to get them. Here's an example.

Last night I'm doing some coding and I want to get some objects that I have written to serialise nicely to Xml. Now I don't want to give them public constructors as they sit within an aggregate, and should only be constructed by the Factory for that aggregate. Also I want to exercise quite a lot of control over the XML that is written. This being the case the use of the XmlSerializer class is pretty much unacceptable to me (see, it's not just because I resent spelling it with a 'z').

Now, pre C# 3.0 I would normally have a method in a helper class somewhere with a method that looked a bit like this.

public static XmlAttribute CreateAttribute(XmlDocument xmlDocument, string name, string value)
{
XmlAttribute newAttribute = xmlDocument.CreateAttribute(name);
newAttribute.Value = value;
return newAttribute;
}

Leaving aside that Helper classes offend me somewhat (if you want to know why then read this book). It would be much nicer if the XmlElement class just had an AppendAttribute method with the suitable overloads which would both create the attribute for me and append it to the element. Well, thanks to the power of extension methods this is very easy to do. Just look at the code below.

public static void AppendAttribute(this System.Xml.XmlElement xmlElement, string name, string value)
{
XmlAttribute newAttribute = xmlElement.OwnerDocument.CreateAttribute(name);
newAttribute.Value = value;
xmlElement.Attributes.Append(newAttribute);
}

public static void AppendAttribute(this System.Xml.XmlElement xmlElement, string prefix, string localName, string namespaceURI, string value)
{
XmlAttribute newAttribute = xmlElement.OwnerDocument.CreateAttribute(prefix, localName, namespaceURI);
newAttribute.Value = value;
xmlElement.Attributes.Append(newAttribute);
}

With this I now just have to make this single, easy, call when I want to add an attribute to an element:

newElement.AppendAttribute("id", _id);

Nice, eh!

* Girlfriend excluded

No comments: