为什么这个C#不会转换为VB?

时间:2009-08-27 18:43:37

标签: asp.net events event-handling

我正在尝试将以下位代码转换为VB(显然将其应用于我自己的解决方案),我从this MSDN article

// 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 个答案:

答案 0 :(得分:6)

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中完成所有这些操作,因此没有必要检查空值,因此,没有必要制作委托的本地副本。