Extension Methods And Null Objects

Sebastien has posted about his use of extension methods on null objects.  I have seen other code with extension methods for IsNull and I have a fundamental disagreement with these types of extension methods.

Extensions methods are syntactic sugar around a static method taking and instance as its first argument.  In C# and VB.NET, they basically make the method feel like an instance method during development, and the compiler takes care of generating the appropriate IL for calling the static method (which is what it really is).

So, what is my problem?  You can’t call an instance method when there is no instance.  Let’s assume I have an instance method defined for all objects:

public static bool IsNull(this object o) { return o == null; }

object o = null;
o.GetHashCode(); //throws an exception.
o.IsNull(); //does not throw an exception.

It doesn’t throw because it is really just a static method underneath being purported to the developer as an instance method.  I think this is a mistake made by the compiler for allowing this, but since it does, it is now an abuse of the language feature.


One thought on “Extension Methods And Null Objects

  1. There is no way for the compiler to prevent a reference being passed from being null, as there is no non-nullable types in .net.

    Optionally the compiler could’ve generated a NRE check on the argument.

    That said, because extension methods are static methods, they get called using call and are inherently very fast. If an extension method was to check for an instance, it’d either have to do this through a new opcode (and break .net 2 compat) or by generating code.

    The code generation will impose the perf penalty for all scenarios, increase the number of bytecodes used for the method, which in turn would reduce the probability of the JIT inlining the method.

    The only reason non-virtual instance methods use callvirt is to ensure the behavior wasn’t confusing (see Eric’s post on this): they changed the behavior to check for null not because of an instant failure but because of a second level that assumed the “this” parameter not to be null.

    Extension methods don’t have this problem, as a NRE will be generated as soon as something uses the null value. The performance cost of the null check and the lack of inlining doesn’t seem to me worth imposing on every call for a failure that is easy to understand.

    That said it’s all conjectures and I can’t say for sure if that’s why they decided to allow for the this param to be null. I’m happy they did, as it allows for some clever language extensions.

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out /  Change )

Google+ photo

You are commenting using your Google+ account. Log Out /  Change )

Twitter picture

You are commenting using your Twitter account. Log Out /  Change )

Facebook photo

You are commenting using your Facebook account. Log Out /  Change )


Connecting to %s