Подтвердить что ты не робот

Как объявить обработчики событий lambda в VB.Net?

Я считаю, что следующий код VB.Net является эквивалентом существующего кода С#; однако тест VB.Net терпит неудачу - обработка событий Lambda никогда не вызывается.

Что происходит?

Версия VB.Net - не удается:

<TestFixture()> _
Public Class TestClass
    <Test()> _
    Public Sub EventTest()
        Dim eventClass As New EventClass
        Dim eventRaised As Boolean = False
        AddHandler eventClass.AnEvent, Function() (eventRaised = True)
        eventClass.RaiseIt()
        Assert.IsTrue(eventRaised)
    End Sub    
End Class

Public Class EventClass
    Public Event AnEvent()
    Public Sub RaiseIt()
        RaiseEvent AnEvent()
    End Sub
End Class

Версия С# - проходит:

[TestFixture]
    public class TestClass
    {
        [Test]
        public void EventTest()
        {
            var eventClass = new EventClass();
            var eventRaised = false;
            eventClass.AnEvent += () => { eventRaised = true; }; 
            eventClass.RaiseIt();
            Assert.IsTrue(eventRaised);
        }
    }

    public class EventClass
    {
        public delegate void EventHandler();
        public event EventHandler AnEvent;
        public void RaiseIt()
        {
            AnEvent();
        }
    }
4b9b3361

Ответ 1

Примечание.. Это относится к более старым версиям VB.net до Visual Studio 2010 и VB.net 10

Разница заключается в том, что в VB.Net выражение lambda должно возвращать значение, то есть они должны быть функциями, а не subs. Выражение лямбда eventRaised = true интерпретируется как булево выражение, а не как присваивание, то есть оценивается как ложное, а не устанавливается в true.

Подробнее о MSDN.

Я не думаю, что шаблон С# для тестирования событий, используемых в примере, может быть выполнен в VB.Net без введения другой функции, например.

<TestFixture()> _
Public Class Test
    <Test()> _
    Public Sub EventTest()
        Dim eventClass As New EventClass
        Dim eventRaised As Boolean = False
        AddHandler eventClass.AnEvent, Function() (SetValueToTrue(eventRaised))
        eventClass.RaiseIt()
        Assert.IsTrue(eventRaised)
    End Sub

    Private Function SetValueToTrue(ByRef value As Boolean) As Boolean
        value = True
        Return True
    End Function

End Class

Public Class EventClass
    Public Event AnEvent()
    Public Sub RaiseIt()
        RaiseEvent AnEvent()
    End Sub
End Class

Ответ 2

Для тех, кто сейчас задает этот вопрос: поскольку Visual Basic 2010 (VB 10.0) анонимный Sub работает, поэтому вы можете написать что-то вроде:

Sub() eventRaised = True

Ответ 3

Короче говоря, вы не можете сделать это в VB на данный момент (это в списке функций, рассмотренных для следующего выпуска). Вы должны использовать объявленный метод и оператор AddressOf.

У команды VB не было времени включать анонимных делегатов на этом языке (это то, что вы пытаетесь использовать, технически не лямбда-выражение).

Лямбда-выражения, которые они должны были реализовать, чтобы Linq мог работать. Анонимные делегаты не требуются ничем (но были бы весьма полезными). Я предполагаю, что они потратили больше времени на завершение таких вещей, как Linq To XML и XML litterals и интеграцию большего числа операторов запроса в синтаксис...