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

Set*_*man 11 .net c# vb.net null events

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

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

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

更多信息

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

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

If myObject.Trigger IsNot Nothing Then  
    ''#do something
End If
Run Code Online (Sandbox Code Playgroud)

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

赛斯

dri*_*iis 11

是.null在Visual Basic中称为"Nothing".

If Trigger IsNot Nothing Then
Run Code Online (Sandbox Code Playgroud)

更新

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

对于此事件定义:

Public Event Trigger as EventHandler
Run Code Online (Sandbox Code Playgroud)

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

If TriggerEvent Is Nothing
Run Code Online (Sandbox Code Playgroud)

请注意VB.Net如何添加带后缀的字段Event来表示委托.有一个在这里寻找一个解释.


Joe*_*orn 9

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

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

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

Public Event Trigger As EventHandler
Friend Sub OnTrigger(ByVal e As EventArgs)
    RaiseEvent Trigger(Me, e)
End Sub
Run Code Online (Sandbox Code Playgroud)


hem*_*emp 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;
    }
}
Run Code Online (Sandbox Code Playgroud)

这是一些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
Run Code Online (Sandbox Code Playgroud)