为什么我不能使用EventHandler <int>而不是从EventArgs

时间:2015-08-04 18:59:18

标签: c# .net

EventHandler<TEventArgs>的文档说:

  

第二个参数是从EventArgs和Supplies派生的类型   保存事件数据所需的任何字段或属性。

似乎通常建议在.Net文档中使用。

然而事实证明我可以做以下工作正常:

public event EventHandler<int> Panned;

并将事件处理程序调用为:

int value = 10;
if (Panned != null)
{
    Panned(this, value);
}

在观察者一方:

subject.Panned += (sender, e) =>
{
    Console.WriteLine(e);
};

对我而言,这似乎比使用EventArgs继承的小类或Does .NET have a built-in EventArgs<T>?

提出的通用EventArgs的小代码乱丢代码更好

那么为什么我需要从EventHandler继承EventArgs泛型参数?

2 个答案:

答案 0 :(得分:18)

如果你需要做的只是将int传递给处理程序,那么你正在做的事情很好。

使用({em>之前的 .NET 4.5),EventHandler类型参数TEventArgs被约束为继承自{{ 1}}但不再是:

EventArgs

MS放弃约束的事实应该告诉你他们太严格了,而你正在做的事情很好。

如果您需要将复杂类型传递给处理程序,那么可能也继承public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e); 出于多态的原因。此外,EventArgs成员也很有用。

答案 1 :(得分:5)

这只是一个惯例。实际上,您甚至不必使用EventHandler<>通用委托。你可以:

public event Action SomeEvent;

public void OnAction()
{
    var a = this.SomeEvent;
    if (a != null)
    {
        a();
    }
}

当然,这个惯例是有原因的。据我所知,每个标准.NET事件都遵循使用返回void的委托的模式,该委托采用object参数和第二个EventArgs参数或派生类型。这样就可以轻松使用这些事件,而无需每次都参考文档。

傻,傻,傻!

这会有效吗?...

class Program
{
    public static event Func<int> SomeEvent;

    static void Main(string[] args)
    {
        SomeEvent += () => 7;
        SomeEvent += () => 8;
        var a = SomeEvent();
        Console.WriteLine(a);
    }
}

我试过了:确实如此!当然,有一个委托有返回值的事件是很奇怪的,因为如果有多个附加处理程序,那么处理程序的值将返回给调用者并不明显。在上面的示例中,结果是8被写入控制台。

有趣,但我怀疑,没用; - )

你会用这个吗?

我不认为拥有非void返回委托类型是明智的,就像在我的例子中一样。但是,出于性能原因,您可能考虑使用其参数为值类型(结构,而不是类)的委托。有可能使用事件而不会导致在堆上分配EventArgs个对象的垃圾收集惩罚。