现在需要EventArg类,我们有generics
使用generics,是否有理由创建特定的派生EventArg类
现在看起来你可以通过通用实现轻松地使用它们。
我应该去看看我的所有示例并删除我的eventArg类(StringEventArgs,MyFooEventArgs等)。
public class EventArgs : EventArgs { public EventArgs(T value) { m_value = value; } private T m_value; public T Value { get { return m_value; } } }
您所描述的基本上是元组 ,用于特定目的的分组值。 它们是函数式编程和支持中非常有用的构造。
缺点是它们的值没有命名,它们需要理解上下文。 EventArgs
本质上通常远离其相关背景而被消耗掉。 因此,元组式的EventArgs
可能会让消费者感到非常困惑。
假设我们有一个事件表明已经完成了一些除法,它带有分子,分母和结果:
public event EventHandler> Divided;
事件处理程序有一些含糊之处:
private void OnDivided(object sender, EventArgs e) { // I have to just "know" this - it is a convention var numerator = e.Value1; var denominator = e.Value2; var result = e.Value3; }
使用表示事件的EventArgs
会更清楚:
private void OnDivided(object sender, DividedEventArgs e) { var numerator = e.Numerator; var denominator = e.Denominator; var result = e.Result; }
通用可重用EventArgs
类以表达意图为代价来简化机制的开发。
看一下Matthew Cochran撰写的Custom Generic EventArgs文章,他在文章中描述了如何使用两个和三个成员进一步扩展它。
使用通用EventArgs有它们的用途,当然还有它们的误用,因为类型信息在这个过程中丢失了。
public class City {...} public delegate void FireNuclearMissile(object sender, EventArgs args); public event FireNuclearMissile FireNuclearMissileEvent; public delegate void QueryPopulation(object sender, EventArgs args); public event QueryPopulation QueryPopulationEvent;
在下面的示例中,它是类型安全的,但更多LOC:
class City {...} public class FireNuclearMissileEventArgs : EventArgs { public FireNuclearMissileEventArgs(City city) { this.city = city; } private City city; public City City { get { return this.city; } } } public delegate void FireNuclearMissile(object sender, FireNuclearMissileEventArgs args); public event FireNuclearMissile FireNuclearMissileEvent; public class QueryPopulationEventArgs : EventArgs { public QueryPopulationEventArgs(City city) { this.city = city; } private City city; public City City { get { return this.city; } } } public delegate void QueryPopulation(object sender, QueryPopulationEventArgs args); public event QueryPopulation QueryPopulationEvent;
正如TcK已经说过:如果你只需要传递一个值,请使用EventArgs
,否则从EventArgs
(或EventArgs
,无论你想要什么)派生。
我认为Tuple风格的EventArgs非常有用。 就像Tuple一样,它们可能被误用,但似乎我的懒惰比我的谨慎感强。 我实现了以下内容:
public static class TupleEventArgs { static public TupleEventArgs Create (T1 item1) { return new TupleEventArgs (item1); } static public TupleEventArgs Create(T1 item1, T2 item2) { return new TupleEventArgs(item1, item2); } static public TupleEventArgs Create(T1 item1, T2 item2, T3 item3) { return new TupleEventArgs(item1, item2, item3); } } public class TupleEventArgs : EventArgs { public T1 Item1; public TupleEventArgs(T1 item1) { Item1 = item1; } } public class TupleEventArgs : EventArgs { public T1 Item1; public T2 Item2; public TupleEventArgs(T1 item1, T2 item2) { Item1 = item1; Item2 = item2; } } public class TupleEventArgs : EventArgs { public T1 Item1; public T2 Item2; public T3 Item3; public TupleEventArgs(T1 item1, T2 item2, T3 item3) { Item1 = item1; Item2 = item2; Item3 = item3; } }
可以如下使用(与事件提升者扩展一起使用时 )
public event EventHandler> NewEvent; NewEvent.Raise(this, TupleEventArgs.Create("1", "2", "3"));