6

Why does the following piece of code work?

call:

SomeObject sO = null;
bool test = sO.TestNull();

code:

public static bool TestNull(this SomeObject sO)
{
    return sO == null;
}

Is this allowed to work or just a bug?

Taylan Aydinli
  • 4,333
  • 15
  • 39
  • 33
Offler
  • 1,223
  • 1
  • 12
  • 34

4 Answers4

13

Is this allowed to work or just a bug?

The code after you've edited the question (to call s0.TestNull() instead of null.TestNull() is meant to work, yes.

Extension methods are just syntactic sugar for calling static methods as if they're instance methods. So a call of:

s0.TestNull()

is converted into

ClassContainingExtensionMethod.TestNull(s0)

... and that's all. No nullity checks are performed automatically.

This can actually be really useful - imagine if string.IsNullOrEmpty had been an extension method - then instead of writing:

if (string.IsNullOrEmpty(foo))

you could write the more readable:

if (foo.IsNullOrEmpty())

However, this power should not be taken lightly - most extension methods should throw ArgumentNullException if the first parameter has a null value, and those which don't should be very clear about it. (It should be relatively rare for such a method not to include Null somewhere in the name.)

Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • 1
    @Moho: This is a compile error. You cannot _compile_ the code `null.TestNull()`. (You could however write `((SomeObject)null).TestNull()`) – Chris Sinclair Nov 28 '13 at 12:57
  • 1
    @Moho: Really? Did you actually try compiling it? I did: "Operator '.' cannot be applied to operand of type '``'" Note that this was before the question was changed to use `s0.TestNull()` – Jon Skeet Nov 28 '13 at 12:59
  • Thanks. I wanted to know wether i can use it for extension methods for comparision of special objects => if s0 = null && a second object which is also put to the extension method is null, both have equal values, therefore it should return true. – Offler Nov 28 '13 at 13:01
  • @Offler: I didn't quite follow that, but hopefully the answer was useful anyway - it's basically fine to do this. – Jon Skeet Nov 28 '13 at 13:01
  • @Offler: you can. The extension method is not really called on that object, it is just about some tricky parameter passing. Your first parameter written as "this Type param" can be NULL. – quetzalcoatl Nov 28 '13 at 13:02
  • @Moho: No, even with a parameter type of `object` it still won't compile when you use a null literal as `null.TestNull()`. – Jon Skeet Nov 28 '13 at 13:03
  • 1
    @Moho: the point here is the `null literal`. That is, precise syntax of `null.Method( .. )` - it is disallowed. If you write it differently, even as `((object)null).Method()`, it is NOT the same, and it is correct! – quetzalcoatl Nov 28 '13 at 13:05
6

Assuming you meant

bool test = sO.TestNull();

Then the answer is just that static functions do not need an instance of the object. Also, calling an extension function is just syntactic sugar for calling the function with parameters.

edit:

I recommend also reading Jon Skeet's answer.

Community
  • 1
  • 1
David S.
  • 5,965
  • 2
  • 40
  • 77
4

The code should be bool test = sO.TestNull();. And yes, that is supposed to work.

You are extending an object with a function, it doesn't matter if the object is null or contains a value. It's essentially the same as writing SomeStaticClass.TestNull(sO);

gehho
  • 9,049
  • 3
  • 45
  • 59
Jensen
  • 3,498
  • 2
  • 26
  • 43
2

As Jon and others already pointed out, this is standard behaviour. It can be useful for

  • Extension methods that raise events and check for nullity before doing so
  • Extension methods that provide chains of Maybes where each part of the chain could be null.

Long time ago I wondered whether it is OK to send messages to null references but time has shown that this is a pretty pragmatic and useful, especially considering the fact that in other languages null references simply do not exist.

flq
  • 22,247
  • 8
  • 55
  • 77