1

当我声明一个事件时,如果事件处理程序有参数,我一直在使用Action委托或委托。Action<T, ...>我最近注意到EventHandler委托的存在,它需要一个继承EventArgs. 后一种方法要求我创建一个附加类,该类仅用于封装随事件传递的任何参数,这似乎是不必要的,除非我遗漏了什么。

那么,在声明事件时使用委托原因是什么?EventArgs它给我买了什么?

4

4 回答 4

3

它使您能够返回事件参数,仅此而已。如果您不需要,那么也许您不需要EventHandler代表。

从更大的角度来看,EventArgs这是使用事件将数据从一个地方获取到另一个地方的“社会可接受的”方式。当然,您可以创建自定义委托来执行此操作,但EventArgs在 Visual Studio 等中具有工具支持。

于 2012-06-06T20:33:35.023 回答
2

它为您提供了一个可扩展点,用于在未来更改您的事件。

假设我定义了一个类Car

public class Car { 
    String Make { get; set; }
    String Model { get; set; }
    int Year { get; set; }
}

和一个事件CarBuilt

public event Action<Car> CarBuilt;

没关系。但是,如果我希望以后的活动包括制造汽车的人呢?使用操作,我需要更改事件签名或将该信息添加到Car类(它确实不属于)。

如果我这样定义它:

public class CarBuiltEventArgs : EventArgs {
    public Car TheCar { get; set; }
}

public event EventHandler<CarBuiltEventArgs> CarBuilt;

然后我可以将 BuiltBy 属性添加到 CarBuiltEventArgs 类中,一切就绪。

public class CarBuiltEventArgs : EventArgs {
    public Car TheCar { get; set; }
    public String BuiltBy { get; set; }
}
于 2012-06-06T20:34:54.710 回答
1

如果需要参数,您表示您使用 Action 。比较这两者,问问自己,如果明年您的需求发生变化并且您需要在该事件中传递一个新参数,那么需要什么?您是更改大量代码还是仅更改一个继承 EventArgs 的类?

于 2012-06-06T20:35:07.347 回答
1

使用的最大原因EventHandler<T>可能是不同类型的委托——即使这些类型使用相同的方法签名——也不能互换。如果一个事件使用 anEventHandler<fnordEventArgs>而另一个使用 an Action<Object, fnordEventArgs>,则可以为这两个事件订阅相同的方法,但为一个事件创建的委托不能与另一个事件一起使用。通常,这没什么大不了的,因为语句 likeFirstEvent += methodName会翻译成FirstEvent += new EventHandler<fnordEventArgs>(methodName),并且SecondEvent += methodName会翻译成FirstEvent += new Action<Object, fnordEventArgs>(methodName)。然而,在某些情况下,事件订阅者需要存储用于订阅的委托。对于存储委托的订阅者,它必须正确地知道它的类型。始终EventHandler<T>用作表单的事件处理方法的委托void EventHandler(Object sender, T args)使得创建正确的委托类型变得更加容易。

于 2012-06-06T21:40:32.997 回答