我一直認爲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