Как объявить обработчики событий lambda в VB.Net?
-
03-07-2019 - |
Вопрос
Я полагаю, что следующий 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), анонимный Sub
s действительно работают, так что вы можете написать что-то вроде:
Sub() eventRaised = True
Короче говоря, на данный момент вы не можете сделать это в VB (это входит в список функций, рассматриваемых для следующего выпуска).Вы должны использовать объявленный метод и оператор AddressOf .
У команды VB не было времени включить анонимных делегатов в язык (который вы пытаетесь использовать, технически это не лямбда-выражение).
Лямбда-выражения, которые они должны были реализовать, чтобы Linq действительно мог работать.Анонимные делегаты ничем не требуются (но были бы весьма полезны).Я предполагаю, что они потратили больше времени на доработку таких вещей, как Linq To XML и XML litterals, и интеграцию большего количества операторов запросов в синтаксис...