C# 如何在 VB.Net 中声明 lambda 事件处理程序?
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/204801/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How to declare lambda event handlers in VB.Net?
提问by Gareth D
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.
我相信下面的 VB.Net 代码相当于前面的 C# 代码;但是 VB.Net 测试失败 - 从未调用过事件处理 Lambda。
What is going on?
到底是怎么回事?
VB.Net version - fails:
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# version - passes:
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();
}
}
采纳答案by Gareth D
Note:This relates to older versions of VB.net Prior to Visual Studio 2010 and VB.net 10
注意:这与 Visual Studio 2010 和 VB.net 10 之前的旧版本 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.
不同之处在于,在 VB.Net 中,lambda 表达式必须返回一个值,即它们必须是函数而不是子函数。lambda 表达式eventRaised = true
被解释为布尔表达式而不是赋值,即计算结果为 false 而不是设置为 true。
Further details on MSDN.
有关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.
我不认为示例中使用的用于测试事件的 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
回答by Denis Troller
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.
长话短说,你暂时不能在 VB 中做到这一点(它在考虑下一个版本的特性列表中)。您必须使用声明的方法和 AddressOf 运算符。
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).
VB 团队没有时间在语言中包含匿名委托(这是您尝试使用的,技术上不是 lambda 表达式)。
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...
他们必须实现 Lambda 表达式,以便 Linq 可以实际工作。任何事情都不需要匿名委托(但会非常有用)。我猜他们花了更多的时间来包装像 Linq To XML 和 XML litterals 这样的东西,并在语法中集成更多的查询运算符......
回答by svick
For those finding this question now: since Visual Basic 2010 (VB 10.0), anonymous Sub
s do work, so you can write something like:
对于那些现在发现这个问题的人:从 Visual Basic 2010 (VB 10.0) 开始,匿名Sub
s 可以工作,因此您可以编写如下内容:
Sub() eventRaised = True