问题描述
可以在IL ..中的空引用上调用实例方法是否正确?
是否有任何示例可以说明这一点。.
Is it correct that a instance method can be called on a null reference in IL..?Is there any example to show this..?
推荐答案
是的,只要方法可以不使用 this
,因为CLR不会对调用
指令进行空检查。
Yes, this is possible, as long as the method doesn't use this
because the CLR does not do a null check for call
instructions.
您必须手动修改IL,因为C#编译器几乎总是生成 callvirt
指令 。
You would have to modify the IL by hand as the C# compiler would almost always generate a callvirt
instruction.
有关详细信息和示例,请参见此博客文章:
See this blog post for details and an example:
样本
.method private hidebysig static void Main(string[] args) cil managed
{
.entrypoint
// Code size 18 (0x12)
.maxstack 1
.locals init ([0] class SomeClass o, [1] string hello)
IL_0000: nop
IL_0001: ldnull
IL_0002: stloc.0
IL_0003: ldloc.0
IL_0004: call instance string SomeClass::GetHello()
IL_0009: stloc.1
IL_000a: ldloc.1
IL_000b: call void [mscorlib]System.Console::WriteLine(string)
IL_0010: nop
IL_0011: ret
}
实际上即使在简单的 call
指令就足够的情况下,C#编译器仍发出 callvirt
的原因是为了防止调用实例空引用上的方法。通过这种编译器行为,用户将获得 NullReferenceException
,从而避免了在空指针上调用方法的怪异情况。埃里克·冈纳森(Eric Gunnerson)前段时间在博客文章中对此进行了解释: 在。
In fact the reason that the C# compiler emits callvirt
even in cases where a simple call
instruction would be sufficient is to prevent calling instance methods on null references. With this behavior of the compiler users will get a NullReferenceException
so the weird situation of calling a method on a null pointer is avoided. Eric Gunnerson explained this in a blog post some time ago: Why does C# always use callvirt? Gishu also has a nice explanation in a related question.
这篇关于在IL中的空引用上调用实例方法的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!