21. January 2011 22:58
One of the quirks of extension methods added to the .NET 3.5 release is that you can add them to interfaces; seemingly adding implementation to interfaces. By definition, in the CLR (and most other languages or platforms) interfaces contain only the signatures of methods, delegates, properties or indexers. By implementing an interface in a class, the body of the method, delegate, property or indexer is added…the implementation is added.
Here I am extending the IMessage interface with a couple of methods for simplifying access to value pairs contained within a IPrimitiveMap (a hash map implementation). A couple of unit tests illustrates the usage:
Truthfully, you are truly adding nothing the interface! No implementation is actually added…basically a static class is created with the extension methods and some compile time kung fu enables you to invoke the method off of the interface definition. Extension methods are not of the domain of the CLR, they are of the domain of the compiler via the System.Runtime.CompilerServices.ExtensionAttribute.
I would imagine this is old news for most seasoned .NET developers, but I just kind of stumbled upon it myself today and thought it was interesting with respect to interfaces and implementation :)
4. November 2009 19:46
If you do any work with xml you probably have come across scenarios where you are using an XmlWriter to produce an output stream of xml. Eventually this output stream is either persisted to disk via an XDocument, sent over the wire using a distributed technology such as WCF, Remoting etc., or possibly transformed with XSL/XSLT. A strong example is custom serialization classes that implement IXmlSerializable. For example:
The class above is a simple data transfer class (DTO) that implements IXmlSerializable so that it can be serialized and/or deserialized from an objet to an xml stream and vice versa. Note: in most cases you would simple mark the class as [Serializable] and/or provide attributes from the System.Xml namespace to provide the same behavior, however in many cases the default implemention will not fit your particular scenario, hence you would implement IXmlSeriable and provide your own custom serialization.
Here is the 'custom' serialization implementation:
While the XmlWriter/XmlReader API's are pretty simple to use, they are also a bit verbose. If you happen to have a fairly large class with many fields, things start to get ugly pretty fast. Typically when I see large classes, I began to think about refactoring into smaller classes when applicable, but that not always the case. Since, most of them time when want serialization/deserialization you simple want to quickly (i.e. less keystrokes) turn the contents and structure of the class into its xml equivalent you are looking at reducing the amount of work needed. This is where extension methods really come in handy:
The result compared to above is a much cleaner, easier to read class:
While extension methods are not new, they do offer unique way of handling situations where you would like to simplify a set of operations without reaching for the traditional static xxxUtil class or creating a customized implementation or wrapper class. In this case, XmlWriter is a class open for extension via basic inheritance, unlike a sealed class such as System.String, which is the intended purpose of extension methods: extended classes closed to inheritance (sealed).
15. June 2009 22:49
I needed to update a utilities class I have been using to support XDocument (not just XmlDocuments) when I hit upon creating an extension method instead of the typical static utility class/method approach. Extension methods are a simple and powerful means of adding behavior to existing classes without breaking encapsulation. I was initially skeptical of the idea, but they have turned out to be rather nice and syntically better than static utilities classes.
The XDocument class is key part of the LINQ to XML
API released with .NET Framework 3.5. Essentially it's a 'next'
generation replacement for the XmlDocument class with added
functionality for easily modifying in-memory Xml documents. Overall I prefer XDocument over XmlDocumentfor various reasons, but learning a new API can be a bit frustrating; it takes time to build a knowledge base of all of the 'gotchas' and 'hacks' ;)
Anyways, here is the final result:
Note that by convention I named the class after the class I was extending and added the 'Extensions' post fix. This makes things a little easier to manage. Here is the usage: