公共事件EventHandler SomeEvent = delegate {};

时间:2011-02-18 09:50:03

标签: c# events

我厌倦了在代码中发现所有这些无用的噪音:

private void RaiseSomeOtherEventIfItIsNotNull()
{
    if (this.SomeOtherEvent != null)
    {
        this.SomeOtherEvent(this, EventArgs.Empty);
    }
}

在99.9%的案例中,我不在乎是否有人附加或者是否为空。刚举起活动!我真的不明白为什么c#编译器让我写下所有这些噪音。

所以我虽然可以宣布这样的事件:

public event EventHandler SomeOtherEvent = delegate { };

这将允许我摆脱无用的空检查和无用的Raise *方法。我可以随时做:

this.SomeOtherEvent(this, EventArgs.Empty);

现在,当我在LutzRöder的Reflector中将标准方法与“my”方法进行比较时,我发现了一些显着的差异。编译器已覆盖Add{}Remove{},还有一个匿名委托的额外静态实例:

[CompilerGenerated] 
private static EventHandler CS$<>9__CachedAnonymousMethodDelegate1;

并且有:

.method private hidebysig static void <.ctor>b__0(object, class [mscorlib]System.EventArgs) cil managed
{
    .custom instance void [mscorlib]System.Runtime.CompilerServices.CompilerGeneratedAttribute::.ctor()
    .maxstack 8
    L_0000: nop 
    L_0001: ret 
}

现在我的问题:你是否看到使用这样的默认初始化来判断事件的任何问题或缺点?

4 个答案:

答案 0 :(得分:7)

您已经展示了额外的方法,但没有显示额外的。额外的方法很好,IMO - 它只是代表无操作处理程序。不是问题。

额外的类有点令人惊讶,因为它正在改变添加/删除行为...编译器总是为事件创建添加/删除方法,因为这是什么使得这是一个事件。

我个人认为这很好 - 但另一种方法是编写扩展方法,例如

public static void Raise<T>(this EventHandler<T> handler, object sender, T args)
    where T : EventArgs
{
    if (handler != null)
    {
        handler(sender, args);
    }
}

public static void Raise(this EventHandler handler, object sender,
                         EventArgs args)
{
    if (handler != null)
    {
        handler(sender, args);
    }
}

然后打电话

myEvent.Raise(this, args);

这适用于所有EventHandlerEventHandler<T>事件。

答案 1 :(得分:1)

microsoft使用的惯例是:

声明这样的事件。

public event EventHandler<ChangedArgs> ItemChanged; 

然后创建一个调用方法

protected virtual void OnItemChanged(ChangedArgs args) 
{
     var handler = ItemChanged; 

     if (handler != null) 
         handler(this, args);
}

这也是ThreadSafe,无论何时举起事件,只需调用OnItemChanged

即可

答案 2 :(得分:0)

据我所知,不,因为这些是非操作处理程序(因为IL生成nopret指令。分配一个空的处理程序几乎与没有处理程序完全相同,即你对该事件一无所知。

答案 3 :(得分:0)

我可能完全错了(如果是这样,请告诉我原因,我现在也很好奇),但也许你需要在课堂级别声明事件委托?

public delegate void SomeEvent(object sender, EventArgs e);