Extension Methods and Null Arguments

A little while ago, I did a DNR TV on C# 3.0. During that, I talked about preserving null semantics when  you write extension methods.  I made the point that you should never test if the first parameter of an extension method is null. That’s because it breaks the semantics of member methods, which is what extension methods appear to be from the calling spot.

For example, this bit of code would throw a null reference exception:

 

SomeType foo = null;

foo.SomeMethod();

 

However, if SomeMethod were actually implemented like this you’d lose error information and let possible error conditions go undetected:

public static Result SomeMethod(this SomeType thing)

{

    if (thing == null)

        return null;

    // etc.

}

 

Clearly that’s bad.  Well, recently one of the folks like saw this DNR TV episode asked me this question:

What is your opinion of checking for null on the first parameter and then throwing an ArgumentNullException?

public static void SendMail(this IEnumerable<Person>

    sequence)
{
    if(sequence == null)
        throw new ArgumentNullException…;
}

That also changes the semantics of the method modulo an instance method. It is more subtle, but it has still changed.

As I said above, de-referencing null throws a NullReferenceException. the sample in the question above throws an ArgumentNullException.

That’s semantically different.

Client code that wants to examine and recover from that coding mistake will be broken. 

Important side bar point: I’m not advocating catching NullReferenceExceptions as a program logic technique (In fact, I think that’s a bad idea).

Even though I don’t want client developers to control program logic by chcking for NullReferenceException, I should ensure that my code obeys the existing semantics.

Well, suppose you changed the SendMail method as follows so it does follow the normal semantics:

public static void SendMail(this IEnumerable<Person>

    sequence)
{
    if(sequence == null)
        throw new NullReferenceException…;
}

Well, now it does obey the semantics of an instance method. That’s good.

However, you’ve now written extra lines of code that don’t do anything useful. If you removed the check, the code would behave exactly the same. As a general rule, I don’t like to write code that doesn’t do anything. (See gratuitous default constructors for an example). 

That’s why I make the practice of not checking null on the first parameter of extension methods.  I don’t write code, and it works correctly.

Created: 10/26/2008 5:00:10 PM

Current Projects

I create content for .NET Core. My work appears in the .NET Core documentation site. I'm primarily responsible for the section that will help you learn C#.

All of these projects are Open Source (using the Creative Commons license for content, and the MIT license for code). If you would like to contribute, visit our GitHub Repository. Or, if you have questions, comments, or ideas for improvement, please create an issue for us.

I'm also the president of Humanitarian Toolbox. We build Open Source software that supports Humanitarian Disaster Relief efforts. We'd appreciate any help you can give to our projects. Look at our GitHub home page to see a list of our current projects. See what interests you, and dive in.

Or, if you have a group of volunteers, talk to us about hosting a codeathon event.