When can this be null in C#?

Is this null?

Today's post at the Daily WTF contains an interesting piece of code: a method that tests whether this is equal to null. Of course, doing that is silly. The value of this can never be null in C#, can it?

If you try to call an instance method on a null reference, a NullReferenceException is always thrown. Except this is not completely true. The exception is actually thrown only if the callvirt IL instruction is used. The alternative (at least for non-virtual methods) instruction call does not check for null. The C# compiler (and probably most other compilers for .Net languages) always emits the safe instruction for instance methods, so it seems we are actually safe.

The problem is, we can use IL directly. The easiest way is to create a DynamicMethod and use the unsafe instruction:

public class Program
{
    static void Main()
    {
        var calledMethod = typeof(Program).GetMethod("IsThisNull");

        var method = new DynamicMethod("testThisNull", typeof(bool), null);
        var il = method.GetILGenerator();
        // pushes null to the stack
        il.Emit(OpCodes.Ldnull);
        // uses the topmost item on the stack for this
        il.Emit(OpCodes.Call, calledMethod);
        // returns the result
        il.Emit(OpCodes.Ret);
        var result = method.Invoke(null, null);
    }

    public bool IsThisNull()
    {
        return this == null;
    }
}

After this code runs, result is a boxed true and no exception was thrown. If we stopped debugger in the IsThisNull() method, we would see that this actually can be null!

The conclusion? While the daily WTF code, that checked whether this is null may theoretically have some reason to exist, it's not necessary in practice. If I was generating an IL to call an instance method, I would always use callvirt, just as C# does. And I suggest you do the same.

dotnet c# il dynamicmethod
Posted by: Petr Onderka
Last revised: 30 Sep, 2014 11:53 PM History

Discussion

20 Jul, 2011 09:32 PM

You did not have to go that far. In all extension methods "this" can be null.

20 Jul, 2011 09:47 PM

linepogl: There is no this in extension methods. There is a this keyword which marks the fact that it is an extension method, but there is no this reference.

Jason W
Jason W
20 Jul, 2011 10:58 PM

C# didn't always emit only the "callvirt" instruction - it was changed between either 1.0 and 1.1 or 1.1 to 2.0.

Petr Onderka
Petr Onderka
21 Jul, 2011 06:00 PM

@Jason, I don't think that's true. This post from Eric Gunnerson (which is, I think, where I read about this for the first time) states that the decision was made long before C# 1.0.

Your Comments

Used for your gravatar. Not required. Will not be public.
Posting code? Indent it by four spaces to make it look nice. Learn more about Markdown.

Preview