在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#方式时要做到这一点有点困难.您显示的示例代码段实际上包含竞争条件,等待发生的错误.更具体地说,它不是线程安全的.您应该创建一个临时变量来捕获当前的事件处理程序集,然后执行null检查.像这样的东西:
EventHandler tmp = Changed; if (tmp != null) { tmp(this,EventArgs.Empty); }
Eric Lippert有一篇关于here的博客文章,受到this Stack Overflow question的启发.
有趣的是,如果你检查使用RaiseEvent关键字的反汇编VB.NET代码,你会发现它正在执行上述正确的C#代码所做的事情:声明一个临时变量,执行空检查,然后调用委托.为什么每次都用这一切混乱你的代码?