如何在 VB.Net 中声明 lambda 事件处理程序?
我相信以下 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();
}
}
I believe the following VB.Net code is the equivalent of the proceeding C# code; however the VB.Net test fails - the event handling Lambda is never called.
What is going on?
VB.Net version - fails:
<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# version - passes:
[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();
}
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
对于现在发现这个问题的人:从 Visual Basic 2010 (VB 10.0) 开始,匿名
Sub
可以工作,因此您可以编写如下内容:For those finding this question now: since Visual Basic 2010 (VB 10.0), anonymous
Sub
s do work, so you can write something like:区别在于,在 VB.Net 中,lambda 表达式必须返回一个值,即它们必须是函数而不是 subs 。 lambda 表达式 eventRaished = true 被解释为布尔表达式而不是赋值,即计算结果为 false,而不是设置为 true。
有关 MSDN 的更多详细信息。
我不认为示例中使用的用于测试事件的 C# 模式可以在 VB.Net 中完成而不引入其他函数,例如
The difference is that in VB.Net a lambda expression must return a value i.e. they must be functions not subs. The lambda expression
eventRaised = true
is being interpreted as a boolean expression rather than an assignment i.e. is evaluating to false rather than setting to true.Further details on MSDN.
I'm don't think the c# pattern for testing events used in the example can be done in VB.Net without introducing another function e.g.
长话短说,您暂时无法在 VB 中执行此操作(它在下一版本考虑的功能列表中)。 您必须使用声明的方法和 AddressOf 运算符。
VB 团队没有时间在该语言中包含匿名委托(这是您尝试使用的,技术上不是 lambda 表达式)。
他们必须实现 Lambda 表达式,这样 Linq 才能真正工作。 任何事情都不需要匿名代表(但非常有用)。 我猜他们花了更多的时间来包装 Linq To XML 和 XML 文本之类的东西,并在语法中集成更多的查询运算符......
Long story short, you cannot do that in VB for the time being (it is on the list of features considered for next release). You have to use a declared method and the AddressOf operator.
The VB team did not have the time to include anonymous delegates in the language (which is what you are trying to use, technically not a lambda expression).
Lambda expressions they had to implement so that Linq can actually work. Anonymous delegates are not required by anything (but would be quite useful). I guess they spent more time on wrapping up things like Linq To XML and XML litterals and integrating more query operators in the syntax...
具有弹出窗口的 WPF 控件需要 WPF 应用程序对象的实例。 在 WPF 应用程序中,这是自动创建的。 WinForm 应用程序中并非如此。 因此,必须手动创建该对象。 应用程序还必须设置为保持打开状态,直到通过代码将其关闭为止,否则当 WinForm 应用程序确定不再需要它时,它将自动关闭。 以下代码将在 WinForm 中打开 Application 对象并使其保持打开状态直至关闭。 推荐的方法是在 WinForm 关闭时关闭 Application 对象。
WPF controls that have popups require an instance of the WPF Application Object. In a WPF application, this is automatically created. This is not the case in a WinForm application. For this reason, this object must be created manually. The Application also must be set to remain open until it is shut down through code, otherwise it will shut automatically when the WinForm applications determines it is no longer needed. The following code will open the Application object in a WinForm and keep it open until it is closed. Shutting down the Application object when the WinForm closes is the recommended approach.