2012-04-22 70 views
0

這是一個有趣的問題,我直到上週與同事進行對話之前從未真正想過。添加事件處理程序 - 語法的目的

當我們添加事件處理程序,我們使用的語法如:

Button1.Click += ClickHandler

至於我可以告訴大家,我們使用+ =同義詞「添加」, - =同義詞「刪除」 。

所以我的問題是,爲什麼語言創建者選擇使用這種語法?爲什麼不Button1.Click.Add(ClickHandler)?

如果它只是意味着添加,爲什麼框架創建者不會爲List而不是.Add()重載+ =運算符?

我想這是解釋在VB.Net中AddHandler和RemoveHandler的存在的相同原因,但我不知道是什麼原因。

爲什麼有添加和刪除事件處理程序的特殊語言語法?

回答

3

非常主觀的問題,定義語法的人不會發布到SO,所以在14年前他們的動機需要閱讀頭腦。無論如何有刺:

事件是一個屬性的確切等效。就像屬性限制對字段的訪問一樣,事件限制對委託對象的訪問。屬性有一個吸氣和一個setter。只需要=符號來調用它們。一個就足夠了,編譯器可以根據屬性標識符相對於=符號的位置(左邊是setter,右邊是getter)來計算setter或getter是否打算。

一個事件有三個訪問器:添加,刪除和提高。沒有在C#中實現Raise(與其他語言不同),所以我們只需要添加和刪除的語法。我們不能只使用一個符號來處理屬性,位置也沒有幫助。添加的最自然的符號是+,刪除的是-。它在邏輯上(並且在實踐中)重新分配底層代理對象,因此它的行爲有點像賦值。所以自然的選擇是+=-=

不知道設計者是否遵循了相同的邏輯。 VB.NET設計者當然沒有,他們選擇語言關鍵字映射到訪問器(AddHandler,RemoveHandler,RaiseEvent)。但C#是語言簡潔和絕對最少數量的關鍵字是強大設計目標的語言。 C++/CLI非常類似於C#,但支持raise訪問器,並且根本沒有語法糖來創建委託對象。這使得它具有超越C#的能力,它不僅限於使這個代表目標,這是一個名爲「unbound delegates」的功能。

最後一點需要注意的是,C#擁有但C++/CLI的委託對象創建語法糖並不重要。因爲如果你把它寫出來,你會得到這樣的代碼:

SystemEvents.UserPreferenceChanged -= new UserPreferenceChangedEventHandler(repaintControls); 

哪一個bedevils從.NET編程開始的任何程序員的頭腦。你必須創建一個新的委託對象以便退訂事件???是的你是。糖更容易理解:

SystemEvents.UserPreferenceChanged -= repaintControls; 

無論如何編譯器會生成相同的代碼。也是VB.NET使用關鍵字的可能原因。

+0

很好的回答!還從Jon Skeet的活動和委託文章中學到了很多:http://csharpindepth.com/Articles/Chapter2/Events.aspx – 2012-04-22 18:27:43

0

這都是品味的問題。由於類似的原因,Java不允許運算符重載。有些人喜歡閱讀文字,有些人喜歡看符號表現形式。

相關問題