views:

185

answers:

4

In C# I can test for this...

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

Is there a way to do this in VB.NET? Test for null I mean?

MORE INFO

I forgot to mention. I have classes written in C# but I am writing my unit tests in VB.NET.

I am trying this in the unit test...

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

This is causing a compile time error which says ... "Public Event Trigger is an Event and cannot be called directly. Use the RaiseEvent statement to raise an event."

Seth

+3  A: 

Yes. null is called "Nothing" in Visual Basic.

If Trigger IsNot Nothing Then

Update

The above answer describes how to check something for null in VB .NET. Unfortunately, events are handled special by the VB.NET compiler. Have a look here for an explanation.

driis
+1, but should null be sacred? ;) I mean come on!
kenny
Thanks for your answer. If you look at my question you will see that Trigger IsNot Nothing causes a compile error in vb.net I forgot to mention that in my question and you answered so fast that you replied before I updated the question. Bottom line...is your code causes a compile error. Seth
Seth Spearman
+1  A: 

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
Joel Coehoorn
Joel ... thanks for your reply. I will update my code. Please see the update to my question (This is my first C# project I am using for learning). In my case I am writing a unit test and the test is checking to verify that a handler registered for the event. But I assume from your answer there is no way to do this in vb.net.
Seth Spearman
+1  A: 

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?

John Saunders
John,Thanks for your answer. It is well taken. I am working on a "learning" project and I am teaching myself both C# and unit testing on it. I guess I am taking the approach of using the unit test to define your api. So I have a method in my class under test call AddTrigger. It will add an object into that collection and at the same time register a trigger in that object. I am REALLY struggling with what to test and what not to test. I realize that there is no point to test .NET or any other external library. But then again...the setup/teardown does define only one trigger registerd.
Seth Spearman
So ... continued...I have two test methods...AddTrigger_TriggerNotExists_TriggerAdded()... AddTrigger_TriggerNotExists_EventRegistered()... Testing the first one is simple...just verifies that an item was added to teh collection. It seemed to make sure that the code..whatever it is...would verify that trigger event was registered. But maybe not.Seth
Seth Spearman
+2  A: 

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
hemp
hemp...thanks for your answer and your recommendation that this is better suited to mocking. I have it on my agenda to learn rhino mocks. Seth
Seth Spearman
Awesome! Thanks for accepting, and hope it helped!
hemp