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

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-03 17:56:47  来源:igfitidea点击:

How to declare lambda event handlers in VB.Net?

c#vb.netunit-testingeventslambda

提问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 = trueis 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 Subs do work, so you can write something like:

对于那些现在发现这个问题的人:从 Visual Basic 2010 (VB 10.0) 开始,匿名Subs 可以工作,因此您可以编写如下内容:

Sub() eventRaised = True