我通過檔案搜索,我發現了很多有關發件人是什麼以及爲什麼你應該使用該模式的問題,但我沒有看到任何關於自定義事件和類型如果發件人。創建自定義事件 - 對象發件人還是類型發件人?
說我創建了一個名爲Subscription的自定義類,它實現了ISubscription,並且我有一些名爲SubscriptionEventArgs的事件參數。如果訂閱有一個事件被稱爲Changed事件簽名Changed(ISubscription sender,SubscriptionEventArgs e)有什麼問題?
一些代碼來幫助推動問題:
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event Action<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event Action<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
如果你只是鄙視用行動到位「事件處理程序」,那麼你可以做同樣的事情,但有一個自定義的通用「事件處理程序」。
public delegate void EventHandler<TSender, TEventArgs>(TSender sender, TEventArgs e);
public class SubscriptionEventArgs : EventArgs
{
// guts of event args go here
}
public interface ISubscription
{
event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
}
public class Subscription : ISubscription
{
public event EventHandler<ISubscription, SubscriptionEventArgs> Changed;
private void OnChanged(SubscriptionEventArgs e)
{
if (Changed!= null)
{
Changed(this, e);
}
}
}
針對漢族的一個樣本事件處理程序的要求:
public class SubscriptionCollection
{
// what is actually holding the subscriptions is not really relevant to the question
private List<ISubscription> _subscriptions;
public SubscriptionCollection()
{
_subscriptions = new List<ISubscription>();
}
public void Add(ISubscription subscription)
{
subscription.Changed += new EventHandler<ISubscription, SubscriptionEventArgs>(Subscription_Changed);
_subscriptions.Add(subscription);
}
private void Subscription_Changed(ISubscription sender, SubscriptionEventArgs e)
{
// Now when the subscription changed event is being handled by the collection
// I don't have to look up the subscription in the list by some key and I don't
// have to cast sender to the correct type because the event handler was typed
// correctly from the beginning.
}
}
在列表中訂閱的查詢可能看起來微不足道,但如果我有非常大的數據集和工作新的數據量將通過實時流應用於應用程序。不得不停止並從列表中獲取參考或執行鑄造步驟的成本沒有意義。他們給了我們2.0中的泛型來解決這個問題,所以我不明白爲什麼我們沒有得到一個通用的事件處理程序,這讓我質疑泛型事件處理程序有什麼問題?
我想如果添加了「where TEventArgs:EventArgs」,則第二塊更多。 – 2010-07-10 22:24:35
只是一個提示,但如果你使用IObservable而不是你的接口類型的ISubscription,我認爲你會更好地遵循設計模式命名,並且可能會更清楚一目瞭然發生了什麼。 – 2010-07-15 05:17:00