开发者

VB.NET: How can I have events return a value like I can in C#?

开发者 https://www.devze.com 2023-04-13 06:16 出处:网络
In C#, I can do this: public partial class _Default : System.Web.UI.Page { protected void Page_Load(object sender, EventArgs e)

In C#, I can do this:

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();
    }
}
开发者_JAVA百科

Notice the line int i = c1.GetInt();. I can't seem to get VB.NET 4.0 to do something similiar. Any help?


I thinks its even easier than most people think...

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

Then in the class that monitors the event...

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

It's all about the ByRef keywords in both the event declaration and the eventhandler sub.


That's not possible in vb.net, events must be raised with the RaiseEvent statement. It doesn't return a value. It is a pretty questionable practice anyway, an event can have zero or multiple subscribers. No telling what the return value might be. Just use a delegate instead:

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


In VB, you don't need to check to see if anyone is attached to your event handler. You can just call RaiseEvent and if anyone is listening to it, it will work. However, the event isn't intended to return a value. You could try sticking it into an event arg and pass that around, but that gets messy.

@HansPassant's solution is close, but not quite what you were asking for. Altering his solution a bit:

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

Alternatively, you could do this without the custom delegate using Lambda's:

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


I found an answer to my issue. In the base class that my ASP.NET user controls inherit, I have this:

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

In my web form codebehind, I wire it up manually to this:

Sub ServeConnection(ByRef Connection As MyConnection)

    Connection = oConn

End Sub

The actual connection is hosted on the webform's codebehind, but I have several user controls that need to use this connection. Any time any of the user controls need the connection, their base class requests it and the host page serves it. This is made possible by the ByRef keyword.

This is the closest C# equivalent I could put together.

0

精彩评论

暂无评论...
验证码 换一张
取 消