The Wiert Corner – irregular stream of stuff

Jeroen W. Pluimers on .NET, C#, Delphi, databases, and personal interests

  • My badges

  • Twitter Updates

  • My Flickr Stream

  • Pages

  • All categories

  • Enter your email address to subscribe to this blog and receive notifications of new posts by email.

    Join 4,269 other subscribers

“C# emits .callvirt instructions, even if the method isn’t virtual. That forces a call site null check.” (Immo Landwerth on Twitter)

Posted by jpluimers on 2025/06/25

From a while back, which I initially missed because it was in the midst figuring out my ver increasing bowel problems leading up to all my cancer treatments, but still relevant:

[Wayback/Archive] Immo Landwerth @terrajobst@hachyderm.io on Twitter: “That’s why C# emits .callvirt instructions, even if the method isn’t virtual. That forces a call site null check.”

Except inside [Wayback/Archive] Extension Methods, referring to this will never return null.

Yes you can work around this using things like reflection, but the C# compiler will emit .callvirt for any method call which does an implicit null check by the caller which means you never have to check that in callees.

The above tweet quoted the first message of the [Wayback/Archive] Thread by @MStrehovsky on Thread Reader App on working around this .callvirt protection:

[Wayback/Archive] Michal Strehovský on Twitter: “1/5 A little know C#/.NET fact is that one can end up in a situation where `this is null` evaluates to true. One just needs a bit of reflection.”

Image

5/5 .NET Native has an optimization that eliminates the entire method bodies on types that were never seen as allocated that also doesn’t play well with this. This makes a good party trick (if the parties you go to are like the parties I go to), but don’t do this in real code

Which in a 2015 comment to [Wayback/Archive] Observing a null this value had an almost identical hack:

Well

class Program
{
    public void Test()
    {
        if (this == null)
            Console.WriteLine("this is null!");
    }

static void Main(string[] args)
{
    Action<program> p_act =  (Action<program>)typeof(Program).GetMethod("Test").CreateDelegate(typeof(Action<program>));
p_act(null);

Console.ReadLine();
    }
}

Delegates obtained with reflection are Magic ehe.

Such extension methods can have specific use cases as shown in another comment to that blog post:

Sometimes I *want* to allow a null `this`, so I do:

public static bool IsNullOrEmpty<t>(this IEnumerable<t> @this)
{
return @this == null || !@this.Any();
}

(and overloads for ICollection and string, as a micro-optimization).

Some interesting comments to the first Tweet:

–jeroen

Leave a comment

This site uses Akismet to reduce spam. Learn how your comment data is processed.