views:

600

answers:

6

Does the method get called with a null value or does it give a null reference exception?

MyObject myObject = null;
myObject.MyExtensionMethod(); // <-- is this a null reference exception?

If this is the case I will never need to check my 'this' parameter for null?

+22  A: 

That will work fine (no exception). Extension methods don't use virtual calls (i.e. it uses the "call" il instruction, not "callvirt") so there is no null check unless you write it yourself in the extension method. This is actually useful in a few cases:

public static bool IsNullOrEmpty(this string value)
{
    return string.IsNullOrEmpty(value);
}
public static void ThrowIfNull<T>(this T obj, string parameterName)
        where T : class
{
    if(obj == null) throw new ArgumentNullException(parameterName);
}

etc

Fundamentally, calls to static calls are very literal - i.e.

string s = ...
if(s.IsNullOrEmpty()) {...}

becomes:

string s = ...
if(YourExtensionClass.IsNullOrEmpty(s)) {...}

where there is obviously no null check.

Marc Gravell
+1, additional note in my answer.
Stefan Steinegger
Marc, you're talking about “virtual” calls – but the same is true for nonvirtual calls on instance methods. I think the word “virtual” here is misplaced.
Konrad Rudolph
@Konrad: It depends on the context. The C# compiler usually uses callvirt even for non-virtual methods, precisely to obtain a null check.
Jon Skeet
I was referring to the difference between call and callvirt il instructions. In one edit I actually tried to href the two Opcodes pages, but the editor barfed at the links...
Marc Gravell
I don't see how this use of extension methods can be any useful, really. Just because it can be done doesn't mean it's right, and as Binary Worrier mentioned below, it looks to me more like an aberration to say the least.
Trap
As they say, YMMV
Marc Gravell
+1  A: 

The extensionmethod is static, so if you don't to anything to the this MyObject it shouldn't be a problem, a quick test should verify it :)

Fredrik Leijon
+4  A: 

A null will be passed to the extension method.

If the method tries to access the object without checking is it null, then yes, it will throw an exception.

A guy here wrote "IsNull" and "IsNotNull" extension methods that check is the reference passed null or not. Personally I think this is an aberration and shouldn't have seen light of day, but it's perfectly valid c#.

Binary Worrier
I agree with you, this only might lead to confusion.
Trap
Indeed, to me it's like asking a corpse "Are you alive" and getting a answer of "no". A corpse can't respond to any question, neither should you be able to "call" a method on a null object.
Binary Worrier
haha! good example! :)
Trap
Ruby does something similar with .nil? - I personally don't see anything wrong with it. It doesn't hurt readability and it can make it more readable - such as a IsNullOrEmpty or any other such combination of expectations.
cfeduke
+8  A: 

Addition to the correct answer from Marc Gravell.

You could get a warning from the compiler if it is obvious that the this argument is null:

default(string).MyExtension();

Works well at runtime, but produces the warning "Expression will always cause a System.NullReferenceException, because the default value of string is null".

Stefan Steinegger
Why would it warn "always cause a System.NullReferenceException". When in fact, it never will?
tpower
Verified - interesting compiler glitch ;-p +1 for ingenuity
Marc Gravell
@tpower: certainly because this check has never been updated to handle extension methods correctly. I found it when I tried to call an extension method that actually only needs the type of the argument, but I didn't have an instance. Now I have to call a static method which is much longer.
Stefan Steinegger
Luckily, we programmers only care about errors, not warnings :p
JulianR
@JulianR: Yes, some do, some do not. In our release build configuration, we treat warnings as errors. So it just doesn't work.
Stefan Steinegger
Thanks for the note; I'll get this in the bug database and we'll see if we can fix it for C# 4.0. (No promise -- since it is an unrealistic corner case and merely a warning, we might punt on fixing it.)
Eric Lippert
@Stefan: Since it's a bug and not a "true" warning, you could use a #pragma statement to supress the warning to get the code pass your release build.
Martin R-L
@Martin: Yes, but this doesn't make sense. Extension methods are only for nicer syntax. If it requires a pragma, it is all for the birds.
Stefan Steinegger
+1  A: 

There are few golden rules when you want in your to be readable and vertical.

  • one worth saying from Eiffel says the specific code encapsulated into a method should work against some input, that code is workable if are met some preconditions and assure an expected output

In your case - DesignByContract is broken ... you are going to perform some logic on a null instance.

ruslander
Bertrand Meyer's such a smart guy
Trap
+1  A: 

As you've already discovered, since extension methods are simply glorified static methods, they will be called with null references passed in, without a NullReferenceException being thrown. But, since they look like instance methods to the caller, they should also behave as such. You should then, most of the time, check the this parameter and throw a NullReferenceException if it's null. It's OK not to do this if the method explicitly takes care of null values and its name indicates it duly, like in the examples below:

public static class StringNullExtensions { 
  public static bool IsNullOrEmpty(this string s) { 
    return string.IsNullOrEmpty(s); 
  } 
  public static bool IsNullOrBlank(this string s) { 
    return s == null || s.Trim().Length == 0; 
  } 
}

I've also written a blog post about this some time ago.

Jordão