为什么这样做?从IL执行方法没有实例

时间:2014-07-03 19:26:28

标签: c# .net il

我正在浏览What's the strangest corner case you've seen in C# or .NET?,这段代码让我思考了一下:

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);
       }
    }
}

我确实理解代码的作用,但我不明白为什么它有效。是不是喜欢做null.Foo()?它的工作方式就像Foo()是静态的一样,而是调用它:Strange.Foo();

请你告诉我我错过了什么?

1 个答案:

答案 0 :(得分:12)

this作为普通参数实现;您的代码只是将null作为此参数传递。

通常抛出NullReferenceException的唯一原因是通常使用CallVirt指令调用方法,该指令对this参数执行vtable查找,如果&#抛出则抛出#{1}} 39; s null。

如果使用call,即使this为空,该方法也会执行完全正常,尽管该方法本身可能会在以后抛出。