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

时间:2010-06-01 19:15:08

标签: c# .net vb.net events null

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

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

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

更多信息

我忘了提。我有用C#编写的类,但我在VB.NET中编写单元测试。

我在单元测试中尝试这个...

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

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

赛斯

6 个答案:

答案 0 :(得分:11)

是。 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的字段来表示委托。有一个look here for an explanation

答案 1 :(得分:8)

首先,您的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

答案 2 :(得分:8)

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

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

在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事件注册了处理程序:

<TestMethod()> _
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

答案 3 :(得分:4)

我相信我在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。如果不太正确,请不要开枪!

答案 4 :(得分:1)

您不应该检查单元测试以查看是否已注册处理程序。你怎么知道它是正确的处理程序,还是它是正确的处理程序但行为不正确?

你的考试有什么意义?

答案 5 :(得分:0)

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

Public Event MyEvent As EventHandler
Public Sub Test()

    Dim test = MyEventEvent
    Dim invokers = test.GetInvocationList()

End Sub

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