如何在VB.Net中声明lambda事件处理程序?

我相信以下VB.Net代码相当于正在进行的C#代码; 但VB.Net测试失败 – 从未调用处理Lambda的事件。

到底是怎么回事?

VB.Net版本 – 失败:

 _ Public Class TestClass  _ 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(); } } 

注意:这与Visual Studio 2010和VB.net 10之前的旧版VB.net有关

不同之处在于,在VB.Net中,lambda表达式必须返回一个值,即它们必须是不是subs的函数。 lambda表达式eventRaised = true被解释为布尔表达式而不是赋值,即评估为false而不是设置为true。

有关MSDN的更多详细信息。

我不认为示例中使用的测试事件的c#模式可以在VB.Net中完成而不引入另一个函数,例如

  _ Public Class 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中做到这一点(它在下一版本考虑的function列表中)。 您必须使用声明的方法和AddressOf运算符。

VB团队没有时间在语言中包含匿名委托(这是您尝试使用的,技术上不是lambda表达式)。

他们必须实现的Lambda表达式才能使Linq实际工作。 任何东西都不需要匿名代表(但是非常有用)。 我猜他们花了更多的时间来完成像Linq To XML和XML litterals这样的事情,并在语法中集成更多的查询运算符……