我一直认为this
在实例方法体内是不可能的。以下简单的程序表明它是可能的。这是一些记录的行为?这个== null里面的.NET实例方法 - 为什么可能?
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();
}
UPDATE
我同意回答说这是怎么这种方法记录在案。但是,我不太了解这种行为。特别是因为这不是C#的设计方式。
我们已经得到了从别人的报告(使用C#的.NET组 的可能一个(还以为是尚未命名C#当时))谁了 编写代码,上一个空叫的方法指针,但他们没有 得到一个异常,因为该方法没有访问任何字段(即 “this”为空,但在方法中没有使用它)。该方法然后调用另一种方法,它使用了这一点,并抛出了一个异常,并且随后出现了一些头部划伤。在他们认为它是 之后,他们给我们发了一张关于它的记录。 我们认为能够调用一个空实例的方法是有点怪异的 。彼得戈尔德做了一些测试,看看哪些性能冲击 总是使用callvirt,并且它足够小,因此我们决定让 进行更改。
http://blogs.msdn.com/b/ericgu/archive/2008/07/02/why-does-c-always-use-callvirt.aspx
请参阅我的回答,指出CLR是有意设计的,就像.NET 1.0一样。你引用的文章是关于一个不同的(非委托)情况,这将是一个编译器优化 - 当静态确定实例的类型时,可以通过直接调用替换“callvirt”。请注意,CLR必须在'callvirt'期间抛出'NullReferenceException'的原因是需要基于'this'引用的VMT查找;不仅仅是检查参考的语义愿望。 –
相关:http://stackoverflow.com/q/3143498/158779 –
恕我直言,很遗憾没有标准方法(可能通过属性)指定应该用'call'而不是'callvirt'调用方法,因为这将允许封装值的类型[例如'string']具有可以在默认值存储位置上操作的成员。说'如果(someString.IsNullOrEmpty)'将比'if(String.IsNullOrEmpty(someString))'更清洁恕我直言。 – supercat