待遇

2010-06-29 69 views
5

我瞭解使用委託類型的簽名事件的好處delegate void delegate_name(object sender, EventArgs e)待遇

一),但除了這個事實,它可以爲我們節省一些打字,是否有任何其他我們應該使用已定義的委託類型EventHandler/EventHandler<T>而不是聲明我們自己的具有簽名delegate void delegate_name(object sender, EventArgs e)的委託類型的原因?

b)兩名其他原因,我可以使用預定義的委託類型EventArgs/EventArgs<T>都認爲:

  • 人食用特定事件(比如event EventHandler my_event)會立刻知道如何使用該事件?

  • 也許一些受歡迎的第三方方法接受作爲參數EventHandler/ EventHandler<T>委託類型,因此,如果有任何的機會,我們的代碼可能會使用這些第三方的方法,我們應該使用預定義的委託EventHandler/Eventhandler<T>

謝謝

回答

11

對我來說,問題是有些奇怪。否則這樣做的好處是什麼(定義與EventHandler<TEventArgs>完全匹配的代表類型TEventArgs)?

也就是說,至少有一個受益我能想到的做「正常」的方式:某些API已經想到對付EventHandler<TEventArgs>代表;例如,Rx Extensions包括類似如下的方法:

Observable.FromEvent<TEventArgs>(
    Action<EventHandler<TEventArgs>> addHandler, 
    Action<EventHandler<TEventArgs>> removeHandler 
); 

如果你定義自己的委託,採用這樣的方法 - 這預計EventHandler<TEventArgs>代表 - 將成爲超過必要的複雜,沒有額外的好處(即無論如何,我可以看到)。

+0

謝謝大家的幫助 – flockofcode 2010-06-29 20:31:55

5

你已經回答了自己的問題:

  • 句法糖(少寫),以維持公約
  • 互操作性(使用EventHandler型讓我們可以輕鬆地從其他圖書館
整合事件

簡而言之,沒有理由不使用它,除非你被迫(通常是人們沒有意識到或不理解它的結果)

7

你忘了一個重要問題:

  • 將保持你的代碼有一天會發現,你住的地方和傷害你的瘋子。
+0

+1這是一個合理的問題,我想! – ewall 2010-06-29 19:20:29

2

Pro C# 2008 and the .NET 3.5 Platform

當編譯器處理事件關鍵字,你會自動與註冊和註銷的方法提供 *以及任何必要的成員變量 **爲您的委託類型。 ...可以肯定的是,事件關鍵字是 只不過是語法糖,因爲它只是爲您節省一些打字時間。

*這包括超載方便的+=-=運營商。

** ...已經標記爲private,所以它們不能結束運行。

當您使用泛型EventHandler委託時,您甚至不必寫出自定義委託類型。

2

我要在這裏搖滾船,並提出一些完全異端的建議。我曾經堅定地在EventArgs陣營,因爲我堅持「MS建議這樣做,而且總是這樣做」的心態,但隨着時間的推移,我開始討厭EventArgs。爲什麼?

  • 它促進了.NET-1.0的編碼風格,它依賴於弱類型/類型轉換,並且使我感到不潔。
  • 它強制實施事件的班級在每次發生火災時用新的EventArg實例污染堆,這也讓我不安。爲什麼不讓我的活動爲訂閱者準確地提供他們需要的內容,而不是將其包裝在一個額外的課堂中,這對我來說什麼都不做。
  • 訂閱事件的回調方法的簽名看起來像垃圾,並且語義細節很少 - 例如, object sender - 什麼是發件人?!?!

我現在所做的是聲明自己的事件處理程序委託,這些委託我整齊地存儲在我的解決方案的自己的「委託」文件夾以及它們自己的命名空間中。所以,我的代表可以駐留在它自己的文件是這樣的:

namespace MyAPI.Data.Delegates 
{ 
    public delegate void DataEventHandler<TData>(DataFeed<TData> sender, TData data); 
} 

事件聲明現在看起來是這樣的:

public event DataEventHandler<TData> DataReady = delegate { }; 

優點這種方法:

  • 方法簽名具有更多的語義詳情。你知道世衛組織正在發送什麼
  • 強打字被保留。沒有更多的東西可以鑄造object sender你認爲它應該是。
  • 你不需要new() up對象並污染堆,如果你的事件頻繁發生,這可能會有問題。只需傳遞您的訂閱者所需的東西,無論是對象引用還是值類型。
  • 通過爲代表使用___EventHandler命名約定,您仍然在爲您的代碼推廣統一樣式,這使API的用戶可以輕鬆地知道您的意圖是什麼。

唯一的「缺點」是它使得代碼的用戶很難將您的事件連接到具有object sender, EventArgs e簽名的現有方法。但是,這一點是沒有意義的,因爲如果你的事件提供了任何額外的數據(例如你創建了你自己的EventArgs子類),那麼他們將不得不改變方法簽名(或者轉換爲你的子類型)。無論哪種方式,這仍然是討厭的。

這就是爲什麼我喜歡我的方式。