The extension method trick
If you’ve been writing C# code lately you should be pretty familiar with extension methods: it’s a nice compiler feature added to C# 3.0 which lets you “attach” methods to an existing type.
So for instance, if you define the following extension method:
static class ConsoleExtensions
{
public static void WriteReversed(this TextWriter writer, string message)
{
writer.WriteLine(new string(message.Reverse().ToArray()));
}
}
You can write:
Console.Out.WriteReversed("hello world!");
You effectively “extended” the TextWriter
type with a new WriteReversed
method in which you get a pseudo-this
reference. Before extension methods, these types of methods would have been in a ConsoleHelper
class of some kind – a lot less discoverable for the clients of your library.
Now, the (not so-)peculiar thing about it is that the pseudo-this
variable can be null
. Indeed, since this whole feature is only syntactic sugar, as they say, it’s just a more elegant way to write the following, which is a plain old function call:
ConsoleExtensions.WriteReversed(Console.Out, "hello world!");
But it means it would look like you’re calling a method on a null
object without getting slapped in the face with the infamous NullReferenceException
.
You just need to add some simple parameter validation code to your extension method:
static class ConsoleExtensions
{
public static void WriteReversed(this TextWriter writer, string message)
{
if (writer != null)
writer.WriteLine(new string(message.Reverse().ToArray()));
}
}
TextWriter writer = null; // woah, are you crazy!?
writer.WriteReversed("hello world!"); // woah, this is crazy!!
This trick can be pretty useful if you have an API that aims to be as minimalist as possible for the user and null
is a valid case for one of the objects exposed publicly. You can already handle this with various well known techniques like wrapping or the NullObject
pattern, but the extension method is a nice new alternative that’s enough in some cases and requires a minimum of code.
I’ve seen that trick used only once so far, in the excellent MvcMiniProfiler:
using (MiniProfiler.Current.Step("Getting the answer to the ultimate question"))
{
var result = DeepThought.Compute();
ViewBag.UltimateAnswer = result;
}
Here, it’s totally OK if you disabled profiling in your web application, which means MiniProfiler.Current
would return null
. That’s because the Step()
method is an extension method that checks for a null
value provided as “this
”, and doesn’t do much in that case.
Sure, they could have abstracted the profiler behind an IProfiler
interface and have the MiniProfiler.Current
return a NullProfiler
when profiling is disabled, or something like that, but that would have been a lot more code than just using an extension method.