In C#, What Happens When You Call an Extension Method on a Null Object

In C#, what happens when you call an extension method on a null object?

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.

why allow extension methods on null objects?

Extension methods are syntactic sugar of the C# language, they get compiled to normal static method calls in ILCode. A static method doesn't know anything about the parameters at compile time.

Instantiate Null Object Inside Extension Method

No - this code doesn't make sense:

TestClass tc = null;
tc.GetTestClass("Some Name");

This could looks like it should throw a NullReferenceException...

OK - so it doesn't (see example on http://www.pvle.be/2008/11/extension-methods-and-null-objects/) but it also doesn't pass tc in by ref either... so it won't update tc for you


MSDN on extensions says:

In general, we recommend that you
implement extension methods sparingly
and only when you have to. Whenever
possible, client code that must extend
an existing type should do so by
creating a new type derived from the
existing type.

http://msdn.microsoft.com/en-us/library/bb383977.aspx


IMO it would be better to implement what you are looking for as some sort of Factory method.

Or you could use something like:

   TestClass tc = new TestClass();
if (tc.TryFillFrom("Some Name"))
{
// do stuff
}
else
{
// handle missing error
}

or you could use a FillFrom method which throws some NotFoundException

Null Reference Exception from extension method

Calling the extension method ChkBoxSelected.ParseItemsToIntegers() is equivalent to calling it using regular static method syntax ParseItemsToIntegers(ChkBoxSelected). The type of ChkBoxSelected is known at compile time, so the compiler can resolve the method.

The NullReferenceException is thrown inside the method it tries to use the ChkBoxSelected.

When calling an instance method, the NullReferenceException is thrown immediately because the CLR checks the actual type of the object to choose correct polymorphic call (even non-virtual methods are called like that).

Should extension methods handle null?

You should throw an ArgumentNullExcception. Most of the .NET Framework extension methods do this. Alternatively, do nothing and let the ObservableCollection<T> constructor do it.

public static ObservableCollection<TSource> ToObservableCollection<TSource>(this     IEnumerable<TSource> source)
{
if (source == null)
{
throw new ArgumentNullException("source");
}

return new ObservableCollection<TSource>(source);
}

Should one always write null-proof extension methods in .NET?

It depends on how you view extension methods. Given that they are merely syntactic sugar on top of a regular static method, I would say that they should follow guidelines for static methods - check all arguments including the this parameter.

This is particularly applicable if you have extensions specifically to handle null - I am aware it is not the preferred use of extensions for most people, but I relish methods like the following:

public static IEnumerable<T> EmptyIfNull<T>(this IEnumerable<T> source)
{
return source ?? Enumerable.Empty<T>();
}

public static void DisposeIfNotNull(this IDisposable source)
{
if (source != null)
source.Dispose();
}

Obviously the parameters must be permitted to be null for these methods to work.

Can I null an object with its own extension method?

This would only be possible if the "this" parameter was also a ref parameter, which it is not.

So the answer is no (in the current C# implementation)

Regarding your other question: there's nothing wrong with the way you implemented it (stopping the timer and clearing the reference to the captured "killingTimer" variable).

null target of extension method

Consider that null can be an argument to a method. Consider also that the extension method foo.Bar<int>(); is really just syntactic sugar for IFooExtensions.Bar<int>(foo); and you will see that, yes, the argument can indeed be null so if you're doing something with the argument, it may certainly be appropriate to test it for null (or simply let a NullReferenceException be thrown, take your pick).

Note: You would not get an exception merely by calling it with a null referenced object, because remember that the method does not actually belong to the object. You only get the exception if (a) you purposefully throw one yourself or (b) the method body actually causes it by trying to work with the instance that is null.



Related Topics



Leave a reply



Submit