vb.net

Action behaving like Func in VB.NET


Today I've witnessed some very strange behavior in VB.NET. The code I am talking about is the following:

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

I know that the code in itself is flawed because I must use :

DoSomething(Sub() thisShouldBeSet = True)

Instead of:

DoSomething(Function() thisShouldBeSet = True)

But I find it very odd that even with Option Strict and Option Explicit On the compile allows me to compile this code.

What is even stranger is that when running the code the Action actually behaves like a Func(of Boolean).

Can anyone provide me with a valid explanation to why this is allowed in VB.NET? Is this a compiler / runtime bug?


Solution

  • Why should it not allow you to compile the code? thisShouldBeSet = True is a valid comparison, returning the value False (because thisShouldBeSet <> True). Remember that = in VB can mean both = (assignment) and == (comparison) in C#, depending on the context.

    To elaborate, Sub() thisShouldBeSet = True would be a shorthand for

    Sub Anonymous()
        thisShouldBeSet = True           ' Assignment
    End Sub
    

    whereas Function() thisShouldBeSet = True is a shorthand for

    Function Anonymous() As Boolean
        Return thisShouldBeSet = True    ' Comparison
    End Sub
    

    In VB, it is explicitly allowed to use a function with a return value as an Action. From the documentation of the System.Action delegate (highlighting by me):

    In C#, the method must return void. In Visual Basic, it must be defined by the Sub…End Sub construct. It can also be a method that returns a value that is ignored.