在VB.NET中提出事件之前如何检查用户 [英] How to check for subscribers before raising an event in VB.NET

查看:109
本文介绍了在VB.NET中提出事件之前如何检查用户的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在C#中,你可以这样做:

In C#, you do something like this:

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

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

But what do you do in VB.NET?

RaiseEvent ,但是

RaiseEvent Changed(Me, EventArgs.Empty)

实际上检查某些已订阅的事件?

actually checking that something has subscribed to the event?

推荐答案

与VB.NET中的C#等价物 RaiseEvent 不同如果没有听众,将不会引发异常,因此首先执行null检查并不是绝对必要的。

Unlike its C# equivalent, RaiseEvent in VB.NET will not raise an exception if there are no listeners, so it is not strictly necessary to perform the null check first.

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

But if you want to do so anyway, there is a syntax for it. You just need to add Event as a suffix to the end of the event's name. (If you don't do this, you'll get a compiler error.) For example:

If ChangedEvent IsNot Nothing Then
    RaiseEvent Changed(Me, EventArgs.Empty)
End If

如上所述,我不太确定这样做有什么真正的好处。它使您的代码非惯用,更难阅读。我在这里介绍的技巧并不是很好地记录在案,大概是因为 RaiseEvent 关键字的全部要点是在后台处理所有这些。这种方式比VB.NET语言的两个设计目标更加方便直观。

Like I said above, though, I'm not really sure if there's any real benefit to doing this. It makes your code non-idiomatic and more difficult to read. The trick I present here isn't particularly well-documented, presumably because the whole point of the RaiseEvent keyword is to handle all of this for you in the background. It's much more convenient and intuitive that way, two design goals of the VB.NET language.

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

Another reason you should probably leave this to be handled automatically is because it's somewhat difficult to get it right when doing it the C# way. The example snippet you've shown actually contains a race condition, a bug waiting to happen. More specifically, it's not thread-safe. You're supposed to create a temporary variable that captures the current set of event handlers, then do the null check. Something like this:

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

Eric Lippert有一篇关于这个 here ,灵感来自于这个堆栈溢出问题

Eric Lippert has a great blog article about this here, inspired by this Stack Overflow question.

有趣的是,如果您检查使用 RaiseEvent 关键字的反汇编VB.NET代码,您会发现它正在完全正确地执行上述正确的 C#代码:声明一个临时变量,执行空检查,然后调用委托。为什么每次都会混淆你的代码?

Interestingly, if you examine disassembled VB.NET code that utilizes the RaiseEvent keyword, you'll find that it is doing exactly what the above correct C# code does: declares a temporary variable, performs a null check, and then invokes the delegate. Why clutter up your code with all this each time?

这篇关于在VB.NET中提出事件之前如何检查用户的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆