我搜索了档案,发现了很多关于发件人是什么以及为什么应该使用该模式的问题,但我没有看到任何有关自定义事件和type如果发件人。
假设我正在创建一个名为 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);
}
}
}
如果您只是鄙视使用操作来代替“EventHandler”,那么您可以做同样的事情,但使用自定义通用“EventHandler”。
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 中为我们提供了泛型来解决这个问题,所以我不明白为什么我们没有得到通用事件处理程序,这让我质疑通用事件处理程序有什么问题?