如何在VB.Net中声明lambda事件处理程序

本文关键字:声明 lambda 事件处理 程序 Net VB | 更新日期: 2023-09-27 17:47:46

我相信下面的VB.Net代码相当于前面的C#代码;但是VB.Net测试失败了——事件处理Lambda从未被调用。

发生了什么事?

VB。网络版本-失败:

<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();
        }
    }

如何在VB.Net中声明lambda事件处理程序

对于那些现在发现这个问题的人:自从Visual Basic 2010(VB 10.0)以来,匿名Sub确实有效,所以你可以写一些类似的东西:

Sub() eventRaised = True

注意:这与Visual Studio 2010和VB.net 10 之前的旧版本VB.net有关

不同之处在于,在VB.Net中,lambda表达式必须返回一个值,即它们必须是函数而不是子函数。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

长话短说,在VB中暂时无法做到这一点(它在下一版本考虑的功能列表中)。您必须使用声明的方法和AddressOf运算符。

VB团队没有时间在语言中包含匿名委托(这是您尝试使用的,从技术上讲不是lambda表达式)。

他们必须实现Lambda表达式,这样Linq才能真正工作。匿名委托不是任何事情都需要的(但会非常有用)。我想他们花了更多的时间来包装像LinqToXML和XML垃圾之类的东西,并在语法中集成更多的查询运算符。。。

具有弹出窗口的WPF控件需要一个WPF应用程序对象实例。在WPF应用程序中,这是自动创建的。WinForm应用程序中的情况并非如此。因此,必须手动创建此对象。应用程序还必须设置为保持打开状态,直到通过代码关闭为止,否则当WinForm应用程序确定不再需要它时,它将自动关闭。以下代码将在WinForm中打开应用程序对象,并将其保持打开状态直至关闭。建议在WinForm关闭时关闭应用程序对象。
  Dim app As System.Windows.Application = New System.Windows.Application With {
            .ShutdownMode = Windows.ShutdownMode.OnExplicitShutdown
        }
        AddHandler Closed, Sub()
                               app.Shutdown()
                           End Sub