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

Kos*_*ukh 15 .net c#

文档EventHandler<TEventArgs>说:

第二个参数是从EventArgs派生的类型,它提供保存事件数据所需的任何字段或属性.

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

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

public event EventHandler<int> Panned;
Run Code Online (Sandbox Code Playgroud)

并调用事件处理程序:

int value = 10;
if (Panned != null)
{
    Panned(this, value);
}
Run Code Online (Sandbox Code Playgroud)

在观察者方面:

subject.Panned += (sender, e) =>
{
    Console.WriteLine(e);
};
Run Code Online (Sandbox Code Playgroud)

对我来说,这似乎不是乱抛垃圾与继承的小类的代码更好的EventArgs或一般EventArgs的建议确实.NET有一个内置的EventArgs <T>?

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

Ale*_*ker 18

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

使用于这样的情况( .NET 4.5)该EventHandler类型参数TEventArgs被约束为从继承EventArgs但不再:

public delegate void EventHandler<TEventArgs>(object sender, TEventArgs e);
Run Code Online (Sandbox Code Playgroud)

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

在您需要将复杂类型传递给处理程序的情况下,您可能还EventArgs因为多态性而继承.此外,该EventArgs.Empty成员是有用的.


Oll*_*lly 5

这只是一个约定。实际上,您甚至不必使用EventHandler<>泛型委托。你可以有:

public event Action SomeEvent;

public void OnAction()
{
    var a = this.SomeEvent;
    if (a != null)
    {
        a();
    }
}
Run Code Online (Sandbox Code Playgroud)

当然,约定是有原因的。据我所知,每个标准的.NET事件都遵循使用带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);
    }
}
Run Code Online (Sandbox Code Playgroud)

我尝试过:可以!当然,发生一个事件,该事件的委托具有返回值是很奇怪的,因为如果有多个附加的处理程序,将哪个处理程序的值返回给调用者并不明显。在上面的示例中,事实证明已将8其写入控制台。

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

你会用这个吗?

我不认为像我的示例那样具有非空返回委托类型是明智的。但是,出于性能原因,您可能考虑使用参数为值类型(结构而不是类)的委托。使用事件可能不会招致EventArgs在堆上分配对象的垃圾回收损失。