Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does this work? Executing method from IL without instance

Tags:

c#

.net

il

I was looking through What's the strangest corner case you've seen in C# or .NET?, and this code made me think a little:

public class Program
{
    delegate void HelloDelegate(Strange bar);

    [STAThread()]
    public static void Main(string[] args)
    {
        Strange bar = null;
        var hello = new DynamicMethod("ThisIsNull",
            typeof(void), new[] { typeof(Strange) },
         typeof(Strange).Module);
        ILGenerator il = hello.GetILGenerator(256);
        il.Emit(OpCodes.Ldarg_0);
        var foo = typeof(Strange).GetMethod("Foo");
        il.Emit(OpCodes.Call, foo);
        il.Emit(OpCodes.Ret);
        var print = (HelloDelegate)hello.CreateDelegate(typeof(HelloDelegate));
        print(bar);
        Console.ReadLine();
    }

    internal sealed class Strange
    {
       public void Foo()
       {
           Console.WriteLine(this == null);
       }
    }
}

I do understand what the code does, but I do not understand why it works. Isn't that like doing null.Foo()? It works as if Foo() is static, and this is being called instead: Strange.Foo();.

Would you please tell me what I am missing?

like image 392
user3439065 Avatar asked Jul 03 '14 19:07

user3439065


1 Answers

this is implemented as a normal parameter; your code simply passes null as this parameter.

The only reason that this would normally throw a NullReferenceException is that methods are usually called using the CallVirt instruction, which does a vtable lookup on the this parameter and throws if it's null.

If you use call, the method will execute perfectly fine even if this is null, although the method itself will likely end up throwing later.

like image 154
SLaks Avatar answered Oct 14 '22 10:10

SLaks