Вопрос

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

Что вообще происходит?

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();
        }
    }
Это было полезно?

Решение 2

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

Разница в том, что в VB.Net лямбда-выражение должно возвращать значение, т.е.это должны быть функции, а не вспомогательные.Лямбда - выражение eventRaised = true интерпретируется как логическое выражение, а не как присваивание , т.е.вычисляется как false, а не как 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

Другие советы

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

Sub() eventRaised = True

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top