Как объявить обработчики лямбда-событий в VB.Net? - PullRequest
20 голосов
/ 15 октября 2008

Я полагаю, что следующий код VB.Net эквивалентен исходному коду C #; однако тест 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

C # версия - пропуска:

[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();
        }
    }

Ответы [ 3 ]

17 голосов
/ 06 января 2013

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

Sub() eventRaised = True
16 голосов
/ 15 октября 2008

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

Разница в том, что в VB.Net лямбда-выражение должно возвращать значение, т. Е. Они должны быть функциями, а не подпрограммами. Лямбда-выражение eventRaised = true интерпретируется как логическое выражение, а не как присваивание, т. Е. Оценивается как ложное, а не как истинное.

Дополнительные сведения о MSDN .

Я не думаю, что шаблон c # для тестирования событий, использованный в примере, может быть выполнен в 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 голосов
/ 19 октября 2008

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

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

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

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