我相信以下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();
}
}
答案 0 :(得分:17)
对于那些现在发现这个问题的人:从Visual Basic 2010(VB 10.0)开始,匿名Sub
可以正常工作,所以你可以这样写:
Sub() eventRaised = True
答案 1 :(得分:16)
注意:这与Visual Studio 2010和VB.net 10之前的旧版VB.net有关
不同之处在于,在VB.Net中,lambda表达式必须返回一个值,即它们必须是函数而不是subs。 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
答案 2 :(得分:2)
长话短说,暂时不能在VB中这样做(它在下一版本考虑的功能列表中)。您必须使用声明的方法和AddressOf运算符。
VB团队没有时间在语言中包含匿名委托(这是您尝试使用的,技术上不是lambda表达式)。
他们必须实现Lambda表达式,以便Linq可以实际工作。任何事情都不要求匿名代表(但是非常有用)。我猜他们花了更多的时间来整理像Linq To XML和XML litterals这样的东西,并在语法中集成更多的查询运算符......
答案 3 :(得分:0)
具有弹出窗口的WPF控件需要WPF应用程序对象的实例。在WPF应用程序中,这是自动创建的。在WinForm应用程序中不是这种情况。因此,必须手动创建该对象。还必须将应用程序设置为保持打开状态,直到通过代码关闭它为止;否则,当WinForm应用程序确定不再需要它时,它将自动关闭。下面的代码将在WinForm中打开Application对象,并将其保持打开状态直到关闭。建议在WinForm关闭时关闭Application对象。
Dim app As System.Windows.Application = New System.Windows.Application With {
.ShutdownMode = Windows.ShutdownMode.OnExplicitShutdown
}
AddHandler Closed, Sub()
app.Shutdown()
End Sub