我正在浏览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();
。
请你告诉我我错过了什么?
答案 0 :(得分:12)
this
作为普通参数实现;您的代码只是将null
作为此参数传递。
通常抛出NullReferenceException
的唯一原因是通常使用CallVirt
指令调用方法,该指令对this
参数执行vtable查找,如果&#抛出则抛出#{1}} 39; s null。
如果使用call
,即使this
为空,该方法也会执行完全正常,尽管该方法本身可能会在以后抛出。