在C#中,你可以这样做:
if (Changed != null)
Changed(this, EventArgs.Empty);
你在VB.NET中做什么?
有RaiseEvent
,但是它是什么呢?
RaiseEvent Changed(Me, EventArgs.Empty)
实际上检查是否有内容订阅了事件?
在C#中,你可以这样做:
if (Changed != null)
Changed(this, EventArgs.Empty);
你在VB.NET中做什么?
有RaiseEvent
,但是它是什么呢?
RaiseEvent Changed(Me, EventArgs.Empty)
实际上检查是否有内容订阅了事件?
与其C#等效项不同,VB.NET中的RaiseEvent
在没有监听器时不会引发异常,因此不一定需要先执行空值检查。
但是,如果您仍然想这样做,有一个语法可以实现。您只需要在事件名称末尾添加Event
作为后缀即可(如果不这样做,则会出现编译器错误)。例如:
If ChangedEvent IsNot Nothing Then
RaiseEvent Changed(Me, EventArgs.Empty)
End If
就像我上面说的那样,我不确定这样做是否有实际好处。它会使你的代码非惯用语并且更难阅读。我在这里介绍的技巧没有被很好地记录下来,可能是因为 RaiseEvent
关键字的整个目的就是在后台处理所有这些内容,这样更加方便和直观,这是 VB.NET 语言的两个设计目标。
另一个你应该让系统自动处理的原因是当按照 C# 的方式进行操作时会比较困难。你展示的示例片段实际上包含一种竞态条件,等待发生错误的 bug。具体来说,它不是线程安全的。你应该创建一个临时变量来捕获当前的事件处理程序,然后再进行空值检查。像这样:
EventHandler tmp = Changed;
if (tmp != null)
{
tmp(this, EventArgs.Empty);
}
Eric Lippert在他的博客文章中详细讨论了此问题,文章链接在这里,受到这个Stack Overflow问题的启发。
有趣的是,如果你检查使用RaiseEvent
关键字的VB.NET代码的反汇编结果,你会发现它正在执行与上面C#代码所做的正确事情一样:声明一个临时变量,进行空值检查,然后调用委托。为什么要每次都让你的代码变得混乱呢?
If Changed IsNot Nothing Then
Changed(Me, EventArgs.Empty)
End If
RaiseEvent
来触发事件,不能直接调用事件。如果没有侦听器,则使用RaiseEvent
不会抛出异常。
参见:http://msdn.microsoft.com/en-GB/library/fwd3bwed(v=vs.71).aspx
因此,应该使用以下内容:
RaiseEvent Changed(Me, EventArgs.Empty)