为事件定义空委托主体是一个好习惯吗?

Kur*_*Liu 23 c# events delegates

可能重复:
在事件声明中添加匿名空委托是否有缺点?

为事件定义一个空委托主体是一个好习惯,这样您就不必担心引发没有事件处理程序的事件了吗?(无需检查事件是否为空).

像下面的代码:

public event EventHandler<LoadEventArgs> LoadedData = delegate { };
Run Code Online (Sandbox Code Playgroud)

Jon*_*eet 39

我当然觉得它很有用,是的.将会有一个微小的,微小的性能成本 - 但不必执行无效测试的可读性的好处使它值得IMO.

值得指出的是,这是使用匿名方法而不是lambda表达式的好几次之一 - 否则你必须命名你将要忽略的参数,如下所示:

public event EventHandler<LoadEventArgs> LoadedData = (sender, args) => {};
Run Code Online (Sandbox Code Playgroud)

我不喜欢说出我不打算使用的东西:)

  • 好吧,你可以cay`(_,__)=> {}`这不比`delegate {}更糟糕 (3认同)
  • 现在有一个?。可以用来代替执行空检查的运算符,例如 MyEvent?.Invoke(); 它可以是一个有用的替代方案。 (2认同)
  • @Anon234_4521:确实,根据https://codeblog.jonskeet.uk/2015/01/30/clean-event-handlers-invocable-with-c-6/ - 但我不会更新我的所有帖子几年前 :) (2认同)

Pie*_*kel 5

我不会这样做。

有两个原因。首先,null在调用它之前简单地检查处理程序是标准的。在示例、Microsoft 参考源和手册中随处可见。

其次,以这种方式初始化事件会在创建类时分配不必要的对象。这会给您的应用程序带来额外的内存压力,而不是真正需要。这是因为:

public event EventHandler<LoadEventArgs> LoadedData = delegate { };
Run Code Online (Sandbox Code Playgroud)

翻译成:

public event EventHandler<LoadEventArgs> LoadedData = new EventHandler<LoadEventArgs>delegate { });
Run Code Online (Sandbox Code Playgroud)

如果您还没有这样做,将您的事件包装在特定的方法中会有很大帮助:

public event EventHandler MyEvent;

protected virtual void OnMyEvent(EventArgs e)
{
    if (MyEvent != null)
        MyEvent(this, e);
}
Run Code Online (Sandbox Code Playgroud)

您可以使用以下方法使该线程安全(r):

public event EventHandler MyEvent;

protected virtual void OnMyEvent(EventArgs e)
{
    var handler = MyEvent;

    if (handler != null)
        handler(this, e);
}
Run Code Online (Sandbox Code Playgroud)

  • 它将创建一个由所有实例共享的额外对象,因为委托不访问任何捕获的变量。(不能保证,但 MS 编译器会这样做。)这会很重要吗?我对此表示怀疑。但是,IMO,有人编写非线程安全版本(根据您的第一个代码片段)的可能性非常大。他们是否真的会从中得到一个 NullReferenceException,谁知道呢……但是你可以打赌它会发生在客户站点而不是测试中……微小的性能下降真的值得额外的代码吗? (7认同)
  • “硬件很便宜,程序员很贵。” “为可维护性而编写,为性能而重构。” “在 97% 的情况下,过早的优化是万恶之源。” 亚达亚达。 (5认同)
  • 不,你没有抓住我第一条评论的重点。虽然 C# 规范不保证,但 MS 编译器至少只会创建委托的 *一个 * 实例。试试看——你会发现一个静态字段,叫做“CS$&lt;&gt;9__CachedAnonymousMethodDelegate1”——如果有必要,构造函数将填充它,然后将引用复制到事件处理程序字段。 (3认同)