动作在VB.NET中表现得像Func

Luc*_*Bos 3 vb.net compiler-construction

今天我在VB.NET中目睹了一些非常奇怪的行为.我正在谈论的代码如下:

Option Strict On
Option Explicit On

Module Module1

    Sub Main()
        Dim thisShouldBeSet = False

        DoSomething(Function() thisShouldBeSet = True)

        If Not thisShouldBeSet Then
            Throw New Exception()
        End If

        Console.WriteLine("yaay")
    End Sub

    Sub DoSomething(action As Action)
        action.Invoke()
    End Sub
End Module
Run Code Online (Sandbox Code Playgroud)

我知道代码本身存在缺陷,因为我必须使用:

DoSomething(Sub() thisShouldBeSet = True)
Run Code Online (Sandbox Code Playgroud)

代替:

DoSomething(Function() thisShouldBeSet = True)
Run Code Online (Sandbox Code Playgroud)

但我觉得很奇怪,即使使用Option Strict和Option Explicit,编译也允许我编译这段代码.

更奇怪的是,在运行代码时,Action实际上表现得像一个Func(布尔值).

任何人都可以向我提供有效解释为什么在VB.NET中允许这样做?这是编译器/运行时错误吗?

Hei*_*nzi 8

为什么不允许你编译代码?thisShouldBeSet = True是一个有效的比较,返回值False(因为thisShouldBeSet <> True).请记住,=在VB中,可以表示C#中的=(赋值)和==(比较),具体取决于上下文.

详细说明,Sub() thisShouldBeSet = True将是一个简写

Sub Anonymous()
    thisShouldBeSet = True           ' Assignment
End Sub
Run Code Online (Sandbox Code Playgroud)

而是Function() thisShouldBeSet = True一个简写

Function Anonymous() As Boolean
    Return thisShouldBeSet = True    ' Comparison
End Sub
Run Code Online (Sandbox Code Playgroud)

在VB中,明确允许使用具有返回值的函数作为Action.从System.Action委托的文档(由我突出显示):

在C#中,该方法必须返回void.在Visual Basic中,它必须由Sub ... End Sub构造定义.它也可以是返回被忽略的值的方法.

  • @Luc:在VB中,动作*可以*具有返回值,该值被忽略.看我的编辑. (2认同)