VB.NET: Как мне сделать так, чтобы события возвращали значение, как в C #? - PullRequest
1 голос
/ 14 октября 2011

В 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 ]

1 голос
/ 14 октября 2011

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

@ Решение 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

В качестве альтернативы, вы можете сделать это без специального делегата, используя лямбда-выражения:

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
1 голос
/ 19 октября 2011

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

фактическое соединение размещено в коде веб-формы, но у меня есть несколько пользовательских элементов управления, которые должны использовать это соединение.Каждый раз, когда любому пользовательскому элементу управления требуется соединение, его базовый класс запрашивает его, и страница хоста обслуживает его.Это стало возможным благодаря ключевому слову ByRef.

Это самый близкий эквивалент C #, который я мог бы сложить.

1 голос
/ 14 октября 2011

Это невозможно в 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
0 голосов
/ 11 апреля 2017

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

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

Это все о ключевых словах ByRef как в объявлении события, так и в подпрограмме обработчика события.

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