Почему этот C # не конвертируется в VB? - PullRequest
1 голос
/ 27 августа 2009

Я пытаюсь преобразовать приведенный ниже бит кода в VB (и, очевидно, применить его к моему собственному решению), который я взял из этой статьи MSDN

// The event. Note that by using the generic EventHandler<T> event type
// we do not need to declare a separate delegate type.
public event EventHandler<ShapeEventArgs> ShapeChanged;

//The event-invoking method that derived classes can override.
protected virtual void OnShapeChanged(ShapeEventArgs e)
{
    // Make a temporary copy of the event to avoid possibility of
    // a race condition if the last subscriber unsubscribes
    // immediately after the null check and before the event is raised.
    EventHandler<ShapeEventArgs> handler = ShapeChanged;
    if (handler != null)
    {
        handler(this, e);
    }
}

Мое преобразование (применимо к моей программе) выглядит следующим образом:

Public Event StatusChanged As EventHandler(Of StatusChangedArgs)

Protected Overridable Sub OnStatusChanged(ByVal e As StatusChangedArgs)
   Dim handler As EventHandler(Of StatusChangedArgs) = StatusChanged 'error here'
   RaiseEvent handler(Me, e)
End Sub

Но я получаю сообщение об ошибке: Public Event StatusChanged(sender As Object, e As StatusChangedArgs) is an event and cannot be called directly. Use a "RaiseEvent" statement to raise an event. Если я правильно конвертирую его, это не имеет смысла, поскольку он скопирован прямо из MSDN, который, я думаю, будет правильным, поэтому, очевидно, я делаю что-то не так. У кого-нибудь есть идеи?

Спасибо ...

1 Ответ

6 голосов
/ 27 августа 2009
RaiseEvent StatusChanged(Me, e)

больше ничего не нужно. Нулевая проверка без необходимости в VB.NET. Это сделано RaiseEvent внутренне.


Ответ на комментарий:

В C # вы сохраняете делегата в локальной переменной, чтобы предотвратить состояние гонки. Если вы вызовете пустой делегат в C #, вы получите NullReferenceException. Чтобы предотвратить это, вы проверяете его, чтобы убедиться, что оно не равно нулю. Если вы напишите это как:

if (StatusChanged != null) { 
   // another thread might set `StatusChanged` to null at this point
   // causing the next line to fail.
   StatusChanged(this, e);
}

Однако, поскольку VB делает все это в RaiseEvent, нет необходимости проверять наличие нулей и, следовательно, нет необходимости создавать локальную копию делегата.

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