2008-09-26 10 views
4

在C#中,我發現自己偶爾想在同一個事件的調度中註冊一個事件的方法。例如,如果我有一個基於同一事件的連續調度來轉換狀態的類,我可能希望第一個狀態的處理程序註銷自己並註冊第二個處理程序。但是,我不希望第二個處理程序被分派,直到下一次事件被解僱。如果我在調度時在c#中註冊一個事件,我保證在調度過程中不會再次調用它嗎?

好消息是,它看起來像微軟的C#實施就像這樣。將事件註冊語法sugar替換爲對System.Delegate.Combine的調用,該調用將當前調用列表和新方法連接成單獨的列表並將其分配給事件屬性。這給了我完全我想要的行爲。

所以,我的問題是:這是由語言標準保證的行爲嗎?我希望能夠在單聲道下的其他平臺上運行我的C#代碼,並且一般都希望確保我沒有根據其實現情況對語言標準進行假設。

我在MSDN上找不到任何明確的信息。

如果你想什麼我談論的一個具體的例子,這裏有一個例子:

delegate void TestDelegate(); 
    static event TestDelegate TestEvent; 

    static void Main (string[] args) { 
     TestEvent += TestDelegateInstanceFirst; 
     TestEvent(); 
     TestEvent(); 
    } 

    static void TestDelegateInstanceFirst() { 
     Console.WriteLine("First"); 
     TestEvent += TestDelegateInstanceSecond; 
    } 

    static void TestDelegateInstanceSecond() { 
     Console.WriteLine("Second"); 
    } 

至少在Windows上,輸出是:

First 
First 
Second 

回答

8

是的,這是保證。

從統一的C#3.0規範,部分15.1:

然而,當兩個非空委託 實例相結合,其 調用列表被連接起來,在 順序左操作數,然後右鍵 操作 - 形成一個新的調用列表, 其中包含兩個或多個條目。

請注意「新的調用列表」。又在第15.3節:

一旦被實例化,委託實例 總是指向同一個目標對象 和方法。請記住,當兩個 代表組合在一起,或者一個從另一個 中刪除時,將有一個新代表 帶有其自己的調用列表; 合併或移除的代表 的調用列表保持不變。

最後,MSDN的System.Delegate規定:

代表是不可改變的;一旦創建, 代理的調用列表確實不會更改 。

我懷疑有什麼東西在CLI規範 - 我查一下,如果你願意,但我希望這三個已經所以基本上給你足夠的信心:)

+0

,稱TestEvent實例化一個委託調用列表是不可變的。並且添加委託會創建另一個調用列表。所以你永遠不能將另一個方法附加到當前正在執行的列表的末尾。 – 2008-09-26 19:46:41

相關問題