如何在VB.NET中引发事件之前检查订阅者



在c#中,您可以这样做:

if (Changed != null)
    Changed(this, EventArgs.Empty);

但是你在VB.NET中做什么呢?

RaiseEvent,但是是

RaiseEvent Changed(Me, EventArgs.Empty)

实际上检查某事是否订阅了事件?

不像c#中的等效RaiseEvent。如果没有侦听器,NET将不会引发异常,因此没有必要先执行空检查。

但是如果你想这样做,有一个语法。您只需要将Event作为后缀添加到事件名称的末尾。(如果不这样做,就会得到编译器错误。)例如:

If ChangedEvent IsNot Nothing Then
    RaiseEvent Changed(Me, EventArgs.Empty)
End If
就像我上面说的,我不确定这样做是否有任何真正的好处。它使您的代码非惯用的,更难以阅读。我在这里介绍的技巧并没有特别详细的说明,大概是因为RaiseEvent关键字的全部意义在于在后台为您处理所有这些。这样更方便和直观,这是VB的两个设计目标。网络语言。

你应该让它自动处理的另一个原因是,用c#的方式来处理它有点困难。您所展示的示例代码片段实际上包含一个竞争条件,一个等待发生的错误。更具体地说,它不是线程安全的。您应该创建一个临时变量来捕获当前事件处理程序集,然后执行空检查。像这样:

EventHandler tmp = Changed;
if (tmp != null)
{
    tmp(this, EventArgs.Empty);
}

Eric Lippert在这里写了一篇很棒的博客文章,灵感来自这个Stack Overflow问题。

有趣的是,如果你检查反汇编的VB。NET代码中使用RaiseEvent关键字时,您会发现它所做的正是上面正确的 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)

相关内容

  • 没有找到相关文章

最新更新