В C# я могу протестировать на это...
public event EventHandler Trigger;
protected void OnTrigger(EventArgs e)
{
if (Trigger != null)
Trigger(this, e);
}
Существует ли способ сделать это в VB.NET? Тест для пустого указателя я имею в виду?
Подробнее
Я забыл упоминать. Мне записали классы в C#, но я пишу свои модульные тесты в VB.NET.
Я пробую это в модульном тесте...
If myObject.Trigger IsNot Nothing Then
''#do something
End If
Это вызывает ошибку времени компиляции, которая говорит... "Триггер Общественного мероприятия является Событием и не может быть назван непосредственно. Используйте оператор RaiseEvent, чтобы сгенерировать событие".
Seth
В вопросе 1129517 есть интересная дискуссия о том, как сделать это именно на C#.
Поскольку класс, содержащий событие, был написан на 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
Во-первых, есть проблема с вашим кодом на 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
Вы не должны использовать модульный тест, проверяющий, зарегистрирован ли обработчик. Как вы узнаете, является ли он правильным обработчиком, или это правильный обработчик, но ведет себя неправильно?
В чем смысл вашего теста?
Да. null в Visual Basic называется "Nothing".
If Trigger IsNot Nothing Then
В приведенном выше ответе описано, как проверить что-то на null в VB .NET. К сожалению, события обрабатываются компилятором VB.NET по-особому.
Для определения этого события:
Public Event Trigger as EventHandler
Вы бы использовали этот код для проверки подписки
If TriggerEvent Is Nothing
Обратите внимание, как VB.Net добавил поле с суффиксом Event
для представления делегата. Посмотрите объяснение здесь.