如何在VB.Net中声明lambda事件处理程序
本文关键字:声明 lambda 事件处理 程序 Net VB | 更新日期: 2023-09-27 17:47:46
我相信下面的VB.Net代码相当于前面的C#代码;但是VB.Net测试失败了——事件处理Lambda从未被调用。
发生了什么事?
VB。网络版本-失败:
<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();
}
}
对于那些现在发现这个问题的人:自从Visual Basic 2010(VB 10.0)以来,匿名Sub
确实有效,所以你可以写一些类似的东西:
Sub() eventRaised = True
注意:这与Visual Studio 2010和VB.net 10 之前的旧版本VB.net有关
不同之处在于,在VB.Net中,lambda表达式必须返回一个值,即它们必须是函数而不是子函数。lambda表达式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
长话短说,在VB中暂时无法做到这一点(它在下一版本考虑的功能列表中)。您必须使用声明的方法和AddressOf运算符。
VB团队没有时间在语言中包含匿名委托(这是您尝试使用的,从技术上讲不是lambda表达式)。
他们必须实现Lambda表达式,这样Linq才能真正工作。匿名委托不是任何事情都需要的(但会非常有用)。我想他们花了更多的时间来包装像LinqToXML和XML垃圾之类的东西,并在语法中集成更多的查询运算符。。。
Dim app As System.Windows.Application = New System.Windows.Application With {
.ShutdownMode = Windows.ShutdownMode.OnExplicitShutdown
}
AddHandler Closed, Sub()
app.Shutdown()
End Sub