2013-07-16 94 views
26

編輯:這不是question的重複,因爲這是一個使用Delegate.CreateDelegate的實際示例,另一個是關於IL的理論討論。除了單詞this和null之外,沒有任何事情可以彼此進行。這怎麼可能是這個== null?

相對於這個question ...

我有一種情況,當一個事件處理程序被調用的實例,它是零。奇怪的。看看圖片:

enter image description here

我不明白髮生了什麼。如何在空實例上調用實例方法?

+0

也許該方法來自該類實現的接口? – pythonian29033

+3

因爲它已經被垃圾收集了?您可能忘記在使用後註銷您的事件處理程序。 – Marcel

+0

也許處理程序所屬的對象已被處置,但處理程序仍然附着於某處的某個事件? – mao47

回答

32

您可以使用Delegate.CreateDelegate重載創建此案例,其中您提供了調用目標的參考null

class Foo 
{ 
    public void Method() 
    { 
     Console.WriteLine(this == null); 
    } 
} 

Action<Foo> action = (Action<Foo>)Delegate.CreateDelegate(
    typeof(Action<Foo>), 
    null, 
    typeof(Foo).GetMethod("Method")); 

action(null); //prints True 

從該網頁上的MSDN備註:

如果firstArgument是一個空引用和方法是一個實例方法, 結果取決於委託類型類型簽名和 方法:

•如果類型的簽名明確包含隱藏的方法的第一個參數 ,則表示委託代表一個開放的 實例方法。調用委託時,參數列表 中的第一個參數將傳遞給隱藏實例參數 方法。

•如果方法和類型匹配的簽名(即,所有參數 類型兼容),則委託所述在 空引用被關閉。調用委託就像在一個空實例上調用一個實例 方法,這對 不是特別有用。

所以它的記錄爲已知的,而且很可能預期,行爲。

+1

+1好的工作發現! –

+0

絕對好,這就是我在用別人的代碼......奇怪。 –

+3

我認爲這是允許的,這很奇怪。我希望'Delegate.CreateDelegate'在這種情況下拋出異常。我想不出一個用例,你想調用沒有實例的實例方法... –