Есть ли способ узнать в VB.NET, зарегистрирован ли обработчик для события? - PullRequest
11 голосов
/ 01 июня 2010

В 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 для вызова события."

Сет

Ответы [ 6 ]

11 голосов
/ 01 июня 2010

Да. null называется «Ничто» в Visual Basic.

If Trigger IsNot Nothing Then

Обновление

Приведенный выше ответ описывает, как что-то проверить на NULL в VB .NET. К сожалению, события обрабатываются специальным образом компилятором VB.NET.

Для этого определения события:

Public Event Trigger as EventHandler

Вы будете использовать этот код для проверки подписок

If TriggerEvent Is Nothing

Обратите внимание, как VB.Net добавил поле с суффиксом Event для представления делегата. Имейте , ищите здесь объяснение .

8 голосов
/ 02 июня 2010

Существует интересная дискуссия 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
8 голосов
/ 01 июня 2010

Прежде всего, есть проблема с вашим кодом C #. Это должно выглядеть следующим образом, чтобы уменьшить вероятность состояния гонки при удалении последнего обработчика в отдельном потоке в неподходящее время (подсказка о том, почему это работает: делегаты с множественным приведением являются неизменными):

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
4 голосов
/ 31 октября 2011

Я считаю, что синтаксис, который я использую для этого в 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 #. Также я где-то читал, что код с назначенной обработчиком проверкой выполняется быстрее, но в данный момент я не могу указать на это, так что вы можете взять или оставить это.

Я думаю, что в любом случае это синтаксис. Пожалуйста, не стреляйте в меня, если это не совсем правильно!

1 голос
/ 01 июня 2010

У вас не должно быть проверки модульного теста, чтобы увидеть, зарегистрирован ли обработчик. Как вы узнали бы, был ли это правильный обработчик, или это был правильный обработчик, но он вел себя неправильно?

Какой смысл вашего теста?

0 голосов
/ 01 ноября 2011

В VB .NET есть интересная языковая «фича». Переменная-член создается для событий, предоставляющих делегат:

Public Event MyEvent As EventHandler
Public Sub Test()

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

End Sub

Вы можете получить список вызовов таким образом.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...