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

查看:270
本文介绍了如何在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?

推荐答案

不像它的C#相当于,的RaiseEvent 在VB.NET会的没有的提高一个异常,如果没有听众,所以它不是严格地需要首先执行空检查

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.

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

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

就像我上面说的,不过,我真的不知道,如果有任何实际的好处这样做。它使你的code不地道,更难以阅读。诀窍我$ P $这里psent不是特别充分证明,presumably因为的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#的方式得到正确处理。该示例代码段,你实际上已经显示包含竞争状态,等待发生的错误。更具体而言,它不是线程安全。你应该创建一个捕获当前组事件处理程序的一个临时变量的然后的做无效的检查。事情是这样的:

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);
}

埃里克利珀有这里这个一个伟大的博客文章< /一>,灵感来自这个堆栈溢出问题

有趣的是,如果你检查拆解VB.NET code,它利用的RaiseEvent 关键字,你会发现它是做什么的上面的正确的的C#code的作用:声明了一个临时变量,执行空检查,然后调用委托。为什么这一切每次弄乱你的code?

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天全站免登陆