有没有办法在VB.NET中知道是否为事件注册了处理程序?

在C#中,我可以测试一下……

public event EventHandler Trigger; protected void OnTrigger(EventArgs e) { if (Trigger != null) Trigger(this, e); } 

有没有办法在VB.NET中执行此操作? 测试null我的意思是?

更多信息

我忘了提。 我有用C#编写的类,但我在VB.NET中编写unit testing。

我在unit testing中尝试这个…

 If myObject.Trigger IsNot Nothing Then ''#do something End If 

这导致编译时错误,该错误表示……“公共事件触发器是一个事件,无法直接调用。使用RaiseEvent语句引发事件。”

赛斯

关于如何在C#中执行此操作,问题1129517中有一个有趣的讨论。

由于包含Event的类是用C#编写的,因此委托语义确实适用,这些技术应该适合您。 但是,您需要将源代码转换为VB.NET以进行unit testing。

给定C#程序集中的以下类:

 public class Triggerific { public event EventHandler Trigger; private static void OnTriggerTriggered(object sender, EventArgs e) { Console.WriteLine("Triggered!"); } public void AddTrigger() { Trigger += OnTriggerTriggered; } } 

这是一些VB.NET代码,它将正确地确定是否为Trigger事件注册了一个处理程序:

  _ Public Sub TriggerTest() Dim cut As New Triggerific cut.AddTrigger() Assert.IsNotNull(GetEventHandler(cut, "Trigger")) End Sub Private Shared Function GetEventHandler(ByVal classInstance As Object, ByVal eventName As String) As EventHandler Dim classType As Type = classInstance.[GetType]() Dim eventField As FieldInfo = classType.GetField(eventName, BindingFlags.GetField Or BindingFlags.NonPublic Or BindingFlags.Instance) Dim eventDelegate As EventHandler = DirectCast(eventField.GetValue(classInstance), EventHandler) ' eventDelegate will be null/Nothing if no listeners are attached to the event Return eventDelegate End Function 

是。 null在Visual Basic中称为“Nothing”。

 If Trigger IsNot Nothing Then 

更新

上面的答案描述了如何在VB .NET中检查null的内容。 不幸的是,事件由VB.NET编译器处理。

对于此事件定义:

 Public Event Trigger as EventHandler 

您将使用此代码来检查订阅

 If TriggerEvent Is Nothing 

请注意VB.Net如何添加带有后缀Event的字段来表示委托。 看看这里的解释 。

首先,你的c#代码存在问题。 它应该像这样读取,以减少在错误的时间删除单独线程中的最后一个处理程序的竞争条件的可能性(暗示它为什么工作:mulit-cast委托是不可变的):

 public event EventHandler Trigger; protected void OnTrigger(EventArgs e) { var temp = Trigger; if (temp != null) temp(this, e); } 

其次,在VB.Net中根本不需要这个代码。 VB处理事件的方式略有不同,因此您根本不应检查是否已注册任何处理程序。 举起活动是安全的,也是首选:

 Public Event Trigger As EventHandler Friend Sub OnTrigger(ByVal e As EventArgs) RaiseEvent Trigger(Me, e) End Sub 

我相信我在VB.Net中使用的语法是:

 Public Event Trigger As EventHandler Friend Sub OnTrigger(ByVal e As EventArgs) If TriggerEvent IsNot Nothing Then RaiseEvent Trigger(Me, e) End If End Sub 

即使TriggerEvent似乎没有被声明,编译器也会理解它。它更接近于模拟C#语法。 此外,我已经读过那个带有处理程序的代码检查运行的代码,但我现在不能指出,所以你可以接受或离开。

无论如何,我认为这就是sytax。 如果不太正确,请不要开枪!

您不应该检查unit testing以查看是否已注册处理程序。 你怎么知道它是否是正确的处理程序,或者它是否是正确的处理程序但行为不正确?

你的测试有什么意义?

VB .NET中有一个有趣的语言“function”。 为公开委托的事件创建成员变量:

 Public Event MyEvent As EventHandler Public Sub Test() Dim test = MyEventEvent Dim invokers = test.GetInvocationList() End Sub 

您实际上可以通过这种方式获取调用列表。