我厌倦了在代码中发现所有这些无用的噪音:
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
}
现在我的问题:你是否看到使用这样的默认初始化来判断事件的任何问题或缺点?
答案 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);
这适用于所有EventHandler
和EventHandler<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生成nop
和ret
指令。分配一个空的处理程序几乎与没有处理程序完全相同,即你对该事件一无所知。
答案 3 :(得分:0)
我可能完全错了(如果是这样,请告诉我原因,我现在也很好奇),但也许你需要在课堂级别声明事件委托?
public delegate void SomeEvent(object sender, EventArgs e);