5

在我读过的所有 .NET 书籍中,实现事件的指南解释了您需要继承EventArgs和使用 EventHandler。我在http://msdn.microsoft.com/en-us/library/ms229011.aspx上查找了更多信息,它说“使用 System.EventHandler 而不是手动创建新的委托以用作事件处理程序。” 我知道使用 EventArgs 有重要的原因,但我的问题不是“我应该这样做吗?”,而是“我可以这样做吗?”。

有什么理由我不能使用通用委托而不是EventHandler我的事件?例如,如果我想要一个强类型的发件人(其他人会因此而烦恼object sender吗?)。

为了更好地解释我的意思,是否有任何理由以下不起作用?

public class IoC
{
    public AbstractFactory GetAbstractFactory()
    {
        var factory = new AbstractFactory();
        factory.CreateObject += ()=>new object();
        return factory;
    }
}
public class AbstractFactory
{
    public event Func<object> CreateObject;

    private object OnObjectCreated()
    {
        if(CreateObject == null)
        {
            throw new Exception("Not injected.");
        }
        return CreateObject();
    }


    private object _injectedObject;
    public object InjectedObject
    {
        get
        {
            if(_injectedObject == null)
            {
                _injectedObject = OnObjectCreated();
            }
            return _injectedObject;
        }
    }
}
4

3 回答 3

6

这只是惯例,对语言没有要求。您可以将任何委托类型用作事件。

标准EventHandler<T>签名虽然有一些优点:

  1. 您可以扩展EventArgs参数。如果您要传递给事件处理程序的每一件事都有一个参数,这将不起作用。
  2. EventArgs接受基类的 EventHandler可以订阅任何遵循约定的事件
  3. 您可以添加EventHandler<T>出现在所有事件上的扩展方法。
  4. 返回类型为void. 其他返回类型作为事件处理程序没有多大意义。
  5. 你遵守约定。遵循约定通常是一个好主意,除非你有令人信服的理由不这样做。
于 2011-02-08T22:00:46.290 回答
3

Microsoft 的所有文档都是关于基类库和/或通用框架设计指南的设计。你可以使用任何你想要的模式。

也就是说,如果人们会使用您的代码,那么如果您遵循 Microsoft 使用的模式,他们会更加熟悉。

于 2011-02-08T22:01:41.867 回答
0

据我所知,EventHandler 和 EventArgs 是最佳实践,但没有什么可以阻止您在事件声明中使用任意委托。event 关键字为您提供了能够 += 和 -= 代表事件槽的特殊功能,而不是简单地拥有一个委托类型的字段或属性,它只接受一个委托(除非您组合多个委托你自己)。

Caveat: I'm unsure what happens to delegates with return values in an event slot. My guess is return values are discarded, since multiple delegates with return values assigned to the event would be hard to handle. This would require some experimentation though.

于 2011-02-08T22:03:39.790 回答