我一直认为在实例方法体内,this
不可能为null。但下面这个简单的程序表明它是可能的。这是某种已记录的行为吗?
class Foo
{
public void Bar()
{
Debug.Assert(this == null);
}
}
public static void Test()
{
var action = (Action)Delegate.CreateDelegate(typeof (Action), null, typeof(Foo).GetMethod("Bar"));
action();
}
更新
我同意那些指出这是文档中所描述的方法的回答。然而,我真的不明白这种行为。特别是因为这不是C#的设计方式。
我们收到了一个报告,来自一些使用C#(虽然当时它还没有被命名为C#)的.NET团体中的某个人编写了调用空指针上的方法的代码,但是他们并没有获得异常,因为该方法没有访问任何字段(即“this”为空,但是方法中没有使用它)。然后该方法调用了另一个方法,该方法确实使用了此指针并抛出了异常,于是有点摸不着头脑。在他们解决问题后,他们给我们发了一张便条。 我们认为能够在空实例上调用方法有点奇怪。Peter Golde进行了一些测试,以查看始终使用callvirt的性能影响如何,结果影响很小,因此我们决定进行更改。
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
callvirt
。请注意,CLR必须在callvirt
期间抛出NullReferenceException
的原因是需要基于这个引用进行VMT查找,而不仅仅是想要检查引用的语义。 - Jirka Hanikacall
而不是callvirt
进行调用,因为这将允许封装值类型[如string
]的类型具有可以操作默认值存储位置的成员。我认为,说if (someString.IsNullOrEmpty)
比if (String.IsNullOrEmpty(someString))
更加简洁。 - supercatthis == null
,因为Unity重载了==
运算符并使用自己的实现方式,这使得this
可以为空。 - Bip901