Why I Love Extension Methods
The other day, I was using for the first time the Html Agility Pack library.
The method I use the most is the SelectNodes to which you give an XPath and that returns an HtlmNodeCollection containing the resulting HtmlNodes or null if no node where found.
I don’t know if this is a design decision, but returning null when there is no match is not very nice. If you use the expression as is in a foreach statement, it will throw a NullReferenceException if no match.
A simple solution is to use the coalescing operator next to the function’s call, in order to give the foreach an empty Enumerable to avoid the exception.
htmlNode.SelectNodes(xpath) ?? Enumerable.Empty<HtmlNode>()
This is working well, but it’s a bit ugly to repeat that in every foreach statement.
This is where Extension Methods are so enjoyable. Let’s just add a new method to our HtmlNode friend that returns an empty enumerable when SelectNodes return null.
internal static class HtmlAgilityPackExtension { internal static IEnumerable<HtmlNode> SelectNodesOrEmpty(this HtmlNode htmlNode, String xpath) { return htmlNode.SelectNodes(xpath) ?? Enumerable.Empty<HtmlNode>(); } }
There we go. From now on, I can simply foreach over a SelectNodesOrEmpty result of any HtmlNode, with no fear of any exception.
"Calling a method on null a reference" by Jon Skeet
Two months ago, I wrote a blog post called Extension Methods and null Objects. In this post, I described how to write Extension Methods in C# 3 and wrote a small sample code to add IsNullOrEmpty as an extension method to the String class. Well, guess what, I found that particular example in a book.
A few weeks ago, I bought Jon Skeet’s book C# in Depth, and have been reading it trough since then (I have to say that it is very well written and a pure joy to read, highly recommended if you are somewhat familiar with C# and would like to polish your knowledge of the language).
Reading part 10.2.4, "Calling a method on a null reference", I was surprised to discover that Jon used exactly the same example as I did! Well, I have to admit that it is I that used the same example as him, as it was already long printed when I wrote that post.
At first it seems odd to be able to call IsNullOrEmpty on a variable that is null without an exception being thrown, particularly if you’re familiar with it as a static method from .NET 2.0. In my view, code using the extension method is more easily understandable. For instance, if you read the expression if (name.IsNullOrEmpty()) out loud, it says exactly what it’s doing.
Nevertheless, I was very pleased with myself and, dare I say it, immediately thought "Great Minds Think Alike" :p.
Extension Methods and null Objects
C# 3.0 allows adding new methods to existing types. These are called Extension Methods. This allow programmers to add methods to existing types, even if they are not partial or event sealed.
These special methods have to be declared in a special way:
- They must be declared within a static class
- They must be static
- The first parameter of the method has to be the type that is "extended", preceded by the this keyword
So, for example, let’s copy the very useful IsNullOrEmpty method as an extension method.
public static class Extensions { public static bool IsNullOrEmpty(this String s) { return String.IsNullOrEmpty(s); } }
String s = ""; s.IsNullOrEmpty();
returns true. You can even do
"".IsNullOrEmpty();
which returns true as well.
Now, all of this is actually an illusion. When the compilers finds
"".IsNullOrEmpty();
Extensions.IsNullOrEmpty("");
So, when an extension method is used, there is one more parameter, that is of the type the extension method is defined on. In this case, String.
But, if it as parameter, it can be null, right? Yes!
String s = null; s.IsNullOrEmpty();
or even
((String) null).IsNullOrEmpty()
will both work, without trowing a NullReferenceException.
Nothing revolutionary here, but I found funny to "call" method on a null object and not have an exception raised.
