In C# I can test for this...
public event EventHandler Trigger;
protected void OnTrigger(EventArgs e)
{
if (Trigger != null)
Trigger(this, e);
}
Yes. null is called "Nothing" in Visual Basic.
If Trigger IsNot Nothing Then
The above answer describes how to check something for null in VB .NET. Unfortunately, events are handled special by the VB.NET compiler.
For this event definition:
Public Event Trigger as EventHandler
You would use this code to check for subscriptions
If TriggerEvent Is Nothing
Notice how VB.Net added a field with the suffix Event
to represent the delegate. Have a look here for an explanation.
There is an interesting discussion in question 1129517 around how to do this very thing in C#.
Since the class that contains the Event was written in C#, the delegate semantics do apply, and those techniques should work for you. However, you'll need to translate the source to VB.NET for your unit test.
Given the following class in a C# assembly:
public class Triggerific
{
public event EventHandler Trigger;
private static void OnTriggerTriggered(object sender, EventArgs e)
{
Console.WriteLine("Triggered!");
}
public void AddTrigger()
{
Trigger += OnTriggerTriggered;
}
}
Here is some VB.NET code which will correctly determine if a handler was registered for the Trigger event:
<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
I believe the syntax I use for this in VB.Net is:
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
Even though TriggerEvent does not appear to be declared the compiler will understand it.It closer emulates the C# syntax. Also I have read somehere that the code with that handler asssigned check runs fater, but I cannot point to that at the moment, so youcan take or leave that.
I think that is the sytax, anyway. Please dont shoot me if it is not quite correct!
First of all, there's a problem with your c# code. It should read like this to reduce the likelihood of a race condition on removing the last handler in a separate thread at just the wrong time (hint on why it works: mulit-cast delegates are immutable):
public event EventHandler Trigger;
protected void OnTrigger(EventArgs e)
{
var temp = Trigger;
if (temp != null)
temp(this, e);
}
Secondly, there's no need for this code at all in VB.Net. VB handles events a little differently, such that you should not check at all whether any handlers are registered. It's safe and preferred to just raise the event:
Public Event Trigger As EventHandler
Friend Sub OnTrigger(ByVal e As EventArgs)
RaiseEvent Trigger(Me, e)
End Sub
You should not have a unit test checking to see if a handler is registered. How would you know whether it was the correct handler, or if it was the correct handler but was behaving incorrectly?
What is the point of your test?
There's an interesting language "feature" in VB .NET. A member variable is created for events that exposes the delegate:
Public Event MyEvent As EventHandler
Public Sub Test()
Dim test = MyEventEvent
Dim invokers = test.GetInvocationList()
End Sub
You can actually get the invocation list this way.