在声明事件时是否有令人信服的理由使用EventHandler <t>委托而不仅仅是Action <t>?</t> </t>

时间:2012-06-06 20:30:35

标签: c# .net events delegates

当我声明一个事件时,如果事件处理程序有参数,我一直在使用Action委托或Action<T, ...>委托。我最近注意到EventHandler委托的存在,它需要一个继承EventArgs的类型参数。后一种方法要求我创建一个额外的类,只存在以封装与事件一起传递的任何参数,这似乎是不必要的,除非我遗漏了一些东西。

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

4 个答案:

答案 0 :(得分:3)

它为你提供了返回事件参数的能力,就是这样。如果您不需要,那么您可能不需要EventHandler代表。

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

答案 1 :(得分: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; }
}

答案 2 :(得分:1)

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

答案 3 :(得分:1)

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