“单行语句 lambdas 必须只包含一个语句。” 为什么会出现这个错误?

Nik*_*wal 2 vb.net lambda

我正在使用 VB.Net 分配一个委托。但是我不想定义方法(子)/函数。

简单地给予Nothing不起作用,因为DelegateCommand如果Nothing在委托中设置,则会引发运行时异常。

那么为什么我会收到这个错误呢?

"Single Line statements lambdas must include exactly one statement."

这是代码

Public Delegate Function DelegateCommand(Of T)(ByVal arg As T) As Boolean

Private _foobar As DelegateCommand(Of Object)
Public ReadOnly Property FooBar() As DelegateCommand(Of Object)
    Get
        If _foobar Is Nothing Then
            _foobar = New DelegateCommand(Of Object)(Sub(), AddressOf OnFooBarCommandExecuted)
        End If
        Return _foobar
    End Get
End Property

Private Function OnFooBarCommandExecuted(ByVal parameter As Object) As Boolean
    Return False
End Function
Run Code Online (Sandbox Code Playgroud)

这是图像

Han*_*ant 5

VB.NET 编译器团队在将 lambda 表达式的支持硬塞到语言中时遇到了相当多的麻烦。用像 Basic 这样的古老的语言绝对不容易做到。您很难生成“最佳”诊断,语言解析器首先失败,因为必须将没有参数的 Sub() 与带有参数的 Function() 匹配。不能这样做,它不知道将什么作为函数参数值传递。更糟糕的是,它需要生成 MSIL 代码来清理堆栈并弹出函数返回值,但是您的 Sub() 说没有代码。这种差异使它大叫 Eeek!用糟糕的诊断和放弃。

在发现代码存在更根本的错误之前,它会尝试将两个方法传递给委托构造函数。你应该知道的更大的问题,不幸的是没有报告,因为它放弃了第一个错误。

Roslyn 项目值得注意,语言解析器被完全重写,它为这段代码生成了更好的诊断。集成到 VS2015 中,您现在可以获得:

错误 BC32008:委托“ConsoleApplication1.Example.DelegateCommand(Of Object)”需要“AddressOf”表达式或 lambda 表达式作为其构造函数的唯一参数。

这会让你在某个地方,注意作为错误消息中的唯一参数。正如错误消息中所暗示的那样,有两种方法可以做到这一点。有效的“AddressOf”表达式作为唯一参数:

    _foobar = New DelegateCommand(Of Object)(AddressOf OnFooBarCommandExecuted)
Run Code Online (Sandbox Code Playgroud)

或者一个 lambda 表达式作为唯一的参数:

    _foobar = New DelegateCommand(Of Object)(Function(parameter)
                                                 Return False
                                             End Function)
Run Code Online (Sandbox Code Playgroud)

不再需要编写 OnFooBarCommandExecuted() 函数,您想要完成的工作。VB.NET 提供了大量的语法糖来进一步简化此代码。您可以声明 lambda 表达式不接受任何参数,即使委托声明了一个参数。而且您不必显式编写委托构造代码,编译器可以从_foobar变量中推断出它。将代码折叠为:

    _foobar = Function() False
Run Code Online (Sandbox Code Playgroud)