Extension methods on a null object instance

Extension methods gave developers with a lot of bandwidth to do interesting (read ‘cool’) things. But there are a couple of things that we need to be aware of while using these extension methods.

I have a StringUtil class that defines two extension methods:

   1: public static class StringUtils
   2: {
   3:     public static string Left(this string arg, int leftCharCount)
   4:     {
   5:         if (arg == null)
   6:         {
   7:             throw new ArgumentNullException("arg");
   8:         }
   9:         return arg.Substring(0, leftCharCount);
  10:     }
  11:  
  12:     public static string Right(this string arg, int rightCharCount)
  13:     {
  14:         if (arg == null)
  15:         {
  16:             throw new ArgumentNullException("arg");
  17:         }
  18:         return arg.Substring(arg.Length - rightCharCount);
  19:     }
  20: }

From the code above, they print the left / right ‘n’ characters of a given string. I can call these methods as:

   1: try
   2: {
   3:     string name = "Arun Mahendrakar";
   4:     Console.WriteLine(name.Left(4));
   5:     Console.WriteLine(name.Right(11));
   6: }
   7: catch (Exception exception)
   8: {
   9:     Console.WriteLine(exception);
  10: }

As expected, the output is:

image

Now what happens if my name variable is null? For normal methods, this would throw a NullReferenceException.

   1: string name = null;
   2: // the below line throws a NullReferenceException
   3: Console.WriteLine(name.StartsWith("abc"));

But apparently you can call an extension method even if the name instance is null. So if I run the below code, I get a ArgumentNullException that is thrown from the Left extension method (which means that the extension method was indeed called).

   1: string name = null;
   2: Console.WriteLine(name.Left(4));
image

Here’s why I think MS allows us to make this call. Forget about extension methods for a moment. Since it is a static method, we can call the Left() as:

   1: string name = null;
   2: StringUtils.Left(name, 4);

Even though name is null, this is a perfectly valid call and it should not throw NullReferenceException exception. In effect, this is the exact same thing we’re doing when we use Left as an extension method. In order to keep the same convention / thinking, it is my opinion that MS allowed us to make this call.

A similar argument follows why I’m throwing an ArgumentNullException and not a NullReferenceException exception. When I say ‘name.Left(4)’, the variable ‘name’ is actually being passed as an argument to the Left extension method – look at the definition of the method to know what I’m talking about.

Continuing about extension methods, LINQ reaped the most benefit from extension methods. Thanks to Jon Skeet, I used his snippet to find the extension methods declared in the System.Linq namespace and there are a whooping 500 such methods. Here’s a complete list if anyone is interested. (For some reason, I cannot do a direct link to the files anymore. The file you’re looking for is the ExtensionMethodsInSystem.LinqNamespace.txt file).

7 Comments

  • Something I didn't know? Anyone who knows what extension methods are should know about the possibility of the this parameter being null, right?

  • @@peSHIr, yes, but not all might know that you CAN call an extension method successfully on a null instance. Plus, if you read very carefully, I've used the 'something you did not know' part, only as a humor (count of 'extension method' in the article).

  • And here’s something YOU did not know: you wasted my time, and (believe me) it was NOT funny at all!
    It's nice to have a little humor when writing about something interesting, but writing about something this obvious and cheat on readers like this???

  • @@Mahdi,
    My blog space is a place for me to write about things I feel I need to share, does not mean it has to be new for EVERYONE on the face of this planet. I'm sure there are people who knew all of this before, that doesn't mean I cannot blog about it.
    There have been times when I have read a few articles where I knew bit of what the author was talking about, now does that mean, I curse myself / the author for having read / written those articles? Doesn't make sense now does it? Think about it.
    Either way - my apologies that your time was wasted on my article!

    Arun

  • @Mahdi - Should we just ask domain owners across the web to run their content by you to see if it can be posted?  I know, you can be the official moderator of the web.

    I can't believe you'd even write a comment like that.  Why not just keep moving rather than discourage the author from providing insight to the .NET community?  Child please.

  • Exceptional post but I was wanting to know if you could write a litte
    more on this subject? I'd be very grateful if you could elaborate a little bit more. Appreciate it!

  • This is a topic that's close to my heart... Cheers! Exactly where are your contact details though?

Comments have been disabled for this content.