关于c#:如何在VB.Net中声明lambda事件处理程序?

How to declare lambda event handlers in VB.Net?

我相信下面的vb.net代码相当于正在进行的C代码;但是vb.net测试失败了-从未调用事件处理lambda。

怎么回事?

vb.net版本-失败:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<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版本-通过:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
[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();
        }
    }

对于那些现在发现这个问题的人来说:自从VisualBasic2010(vb 10.0)以来,匿名Sub就开始工作了,因此您可以编写如下内容:

1
Sub() eventRaised = True


Note: This relates to older versions of VB.net Prior to Visual Studio 2010 and VB.net 10

区别在于,在VB.NET中,lambda表达式必须返回一个值,即它们必须是函数而不是subs。lambda表达式eventRaised = true被解释为布尔表达式,而不是赋值,即计算为假而不是设置为真。

有关msdn的更多详细信息。

我不认为该示例中使用的测试事件的C模式可以在VB.NET中完成,而无需引入其他函数,例如。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
<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才能实际工作。匿名委托不需要任何东西(但非常有用)。我想他们花了更多的时间来包装诸如linq-to-xml和xml-litterals之类的东西,并在语法中集成更多的查询操作符…