在 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# 等价物不同,RaiseEvent
在 VB.NET 中,如果没有侦听器,则不会引发异常,因此没有必要首先执行 null 检查。
但是,如果你想这样做,它有一个语法。您只需Event
在事件名称的末尾添加一个后缀即可。(如果你不这样做,你会得到一个编译器错误。)例如:
If ChangedEvent IsNot Nothing Then
RaiseEvent Changed(Me, EventArgs.Empty)
End If
不过,就像我上面所说的那样,我不确定这样做是否有任何真正的好处。它使您的代码不习惯并且更难阅读。我在这里介绍的技巧并不是特别有据可查,大概是因为RaiseEvent
关键字的全部意义在于在后台为您处理所有这些。这种方式更加方便和直观,这是 VB.NET 语言的两个设计目标。
您可能应该让它自动处理的另一个原因是因为在使用 C# 方式时很难正确处理它。您显示的示例片段实际上包含一个竞争条件,一个等待发生的错误。更具体地说,它不是线程安全的。您应该创建一个捕获当前事件处理程序集的临时变量,然后进行空检查。像这样的东西:
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
必须用于在 VB.NET 中引发事件,不能简单地调用事件。RaiseEvent
如果没有侦听器,则不会引发异常。
请参阅:http: //msdn.microsoft.com/en-GB/library/fwd3bwed (v=vs.71).aspx
因此,应使用以下内容:
RaiseEvent Changed(Me, EventArgs.Empty)