VB.NET:我怎样才能让事件在C#中返回一个值?

时间:2011-10-14 16:21:54

标签: vb.net events delegates

在C#中,我可以这样做:

public partial class _Default : System.Web.UI.Page
{
    protected void Page_Load(object sender, EventArgs e)
    {
        Class1 c1 = new Class1();

        c1.OnNeedInt += new Class1.NeedInt(c1_OnNeedInt);

        int i = c1.GetInt();
    }

    int c1_OnNeedInt()
    {
        return 1;
    }
}

public class Class1
{
    public delegate int NeedInt();
    public event NeedInt OnNeedInt;

    public int GetInt()
    {
        return OnNeedInt == null ? 0 : OnNeedInt();
    }
}

注意第int i = c1.GetInt();行。我似乎无法让VB.NET 4.0做类似的事情。有什么帮助吗?

4 个答案:

答案 0 :(得分:1)

这在vb.net中是不可能的,必须使用RaiseEvent语句引发事件。它不返回值。无论如何,这是一个非常值得怀疑的做法,一个事件可以有零个或多个订阅者。不知道返回值可能是什么。只需使用代理:

Class Page
    Public Sub New()
        Dim obj As New Class1
        Dim dlg As New Func(Of Integer)(AddressOf obj.GetInt)
        Dim i As Integer = dlg()
    End Sub
End Class

Class Class1
    Public Function GetInt() As Integer
        Return 42
    End Function
End Class

答案 1 :(得分:1)

在VB中,您无需检查是否有人附加到您的事件处理程序。你可以调用RaiseEvent,如果有人正在听它,它会工作。但是,该事件不是为了返回值。您可以尝试将其粘贴到事件arg并传递它,但这会变得混乱。

@ HansPassant的解决方案很接近,但并不是你所要求的。改变他的解决方案:

Delegate Function FetchIt() As Integer
Class Page
    Public Sub New()
        Dim obj As New Class1
        Dim i As Integer = obj.GetInt(AddressOf c1_OnNeedInt)
    End Sub
    Function c1_OnNeedInt() As Integer
        Return 42
    End Function
End Class

Class Class1
    Public Function GetInt(fetcher As FetchIt) As Integer
        Return fetcher()
    End Function
End Class

或者,您可以在没有使用Lambda的自定义委托的情况下执行此操作:

Class Page
    Public Sub New()
        Dim obj As New Class1
        Dim dlg As New Func(Of Integer)(AddressOf c1_OnNeedInt)
        Dim i As Integer = obj.GetInt(dlg)
    End Sub
    Function c1_OnNeedInt() As Integer
        Return 42
    End Function
End Class

Class Class1
    Public Function GetInt(fetcher As Func(Of Integer)) As Integer
        Return fetcher()
    End Function
End Class

答案 2 :(得分:1)

我找到了问题的答案。在我的ASP.NET用户控件继承的基类中,我有这个:

Dim _Connection As MyConnection
Public Property Connection As MyConnection
    Get
        If _Connection Is Nothing Then
            RaiseEvent OnNeedConnection(_Connection)
        End If
        Return _Connection
    End Get
    Set(value As MyConnection)
        _Connection = value
    End Set
End Property

Public Delegate Sub NeedConnection(ByRef Connection As MyConnection)
Public Event OnNeedConnection As NeedConnection

在我的网络表单代码隐藏中,我手动将其连接到:

Sub ServeConnection(ByRef Connection As MyConnection)

    Connection = oConn

End Sub

实际连接托管在webform的代码隐藏上,但我有几个需要使用此连接的用户控件。只要任何用户控件需要连接,它们的基类就会请求它并且主机页面为它提供服务。这可以通过ByRef关键字实现。

这是我可以放在一起的最接近的C#等价物。

答案 3 :(得分:0)

我认为它比大多数人认为的更容易......

Class MyClass
   Public Event MyEvent(ByRef MyVariable as String)

   Private Sub DoSomething()
       Dim SomethingINeed as String = String.Empty
       RaiseEvent MyEvent(SomethingINeed)

       'SomethingINeed will now contain "Goodbye Cruel World"

   End sub

End Class

然后在监控事件的班级......

Class MyOtherClass

    Private Sub New()
        AddHandler MyClass.MyEvent, Addressof MyEventHandler
    End Sub

    Private Sub MyEventHandler(ByRef StringToPassBack as String)
        StringToPassBack = "Goodbye Cruel World"
    End Sub

End Class

所有关于事件声明和eventhandler子句中的 ByRef 关键字。