2009-08-27 95 views
8

我對用C#移除事件處理程序的語法感到困惑。C#事件刪除語法

Something += new MyHandler(HandleSomething); // add 
Something -= new MyHandler(HandleSomething); // remove 

「新」創建在每行一個新的對象,所以你添加一個對象 ,然後要求它刪除不同的對象。

實際上,這可以起到什麼作用?
從語法上來看,這肯定不明顯。

+3

刪除對象會在代理列表中搜索與給定對象的目標和方法匹配的對象,並將其刪除。 – 2009-08-27 15:51:34

+0

你不必使用新的MyHandler,它只是一個委託包裝。 – 2009-08-27 15:53:18

+0

回答此線程:http://stackoverflow.com/questions/1178725/how-to-unset-event也有一些關於這個問題的討論。 – JeffH 2009-08-27 16:21:29

回答

19

的+ =和 - =是內置內部方法名稱爲Add()語法的快捷方式,並刪除(),其添加或刪除一個指針委託人作爲私人字段的內部代表委託人鏈接列表。運行Remove時,它將從鏈接列表的頭部開始,逐個檢查列表中的每個委託,直到找到與傳遞給Remove()方法的值相等的值。 (使用 - =語法)

然後,它會刪除一個從鏈表和補丁鏈表保留它的連接...

在此背景下,「等於」方法(委託())將被覆蓋,這樣它只會比較委託的目標和methodPtr,即使您創建了一個新委託來傳遞給Remove,它也是一樣的...

-1

您可以將事件視爲佔位符方法,用於引發事件時執行的委託邏輯。單個事件可以有多個訂閱者(多播),因此+ =和 - =語法是單個事件處理程序如何附加或刪除。簡單地進行分配會重置事件的訂閱,這可能會導致不必要的副作用。

編輯:this link詳細解釋了在C#事件觸發

+1

downvote請原因? – 2009-08-27 15:49:15

+0

爲什麼要投票?這似乎是一個非常有效的迴應。 – 2009-08-27 15:50:07

+0

重申OP的問題:「爲什麼我們可以+ =一個新物體,以及 - =一個完全不同的新物體並獲得預期效果?」 Josh E不回答*爲什麼*我們可以附加'a'並刪除'b',其中'a'和'b'是不同的實例,並且仍然可以得到我們想要的。 – JeffH 2009-08-27 16:16:59

7

「new MyHandler」is實際上多餘。你可以簡單地做

Something += HandleSomething; // add 
Something -= HandleSomething; // remove 

在C#中的所有事件都多路廣播委託,所以+ =和 - =語法表示您要添加/刪除委託代表的名單將被調用。

至於幕後發生了什麼,我找到的最好的解釋是Jon Skeet's

+0

這實際上與提供的示例相同,儘管較新的C#爲您添加了它。 – Dykam 2009-08-27 15:52:59

+0

你可以離開new'ing了,但如果你讓Visual Studio通過輸入:「Something + =」然後填寫它,自動生成的代碼將完成它類似於:「Something + = new MyHandler(HandleSomething );」 OP正在問引擎蓋下發生了什麼,這樣新的方式就起作用了。 – JeffH 2009-08-27 16:16:07

+0

是的,我最終被叫走,沒有足夠的時間來完成答案。兩種語法都是相同的,編譯器推斷委託並向多播列表添加新實例。即使在刪除時,「新的EventHandler()」語法也能工作,因爲它查看目標&方法簽名而不是特定的對象ref。 – womp 2009-08-27 16:39:40