Thursday, May 18, 2023

Watch your enums

I just fixed a bug that caught me by surprise. I know enums are just integers internally, but I always assumed that if you try to compare enums of different types, you would get a build error. You don't.

Start a new Visual Studio VB console application and call it WrongEnum. I used .Net Core 6.0. Make Program.vb look like this.

Option Strict On
Module Program
    Public Enum Enum1
        Success
        Fail
    End Enum
 
    Public Enum Enum2
        Fail
        Success
    End Enum
 
    Sub Main(args As String())
 
        Dim e As Enum1 = Enum1.Success
        If e = Enum2.Success Then
            Console.WriteLine("Success!")
        Else
            Console.WriteLine("Fail")
        End If
        Console.Read()
    End Sub
End Module

I would have thought the line starting If e = would cause a build error because Enum1 shouldn't be comparable to Enum2. But they're both integers, so I guess the compiler is OK with it. Still, not even a warning?

Run the program and it displays "Fail", even though e was initialized as Success. 

Update:

You can also pass the wrong type of enum to a method although this causes a build error if you have Option Strict On.

Consider the method below. You can call it with Enum1 or even an integer when Option Strict is Off. ie PrintSuccess(Enum1.Success). It writes "Fail" to the console.

If you call the method with an integer that is in range it writes the enum's name but if you call it with an integer that is out of range it writes the integer.

        PrintSuccess(Enum1.Success)
        PrintSuccess(1)
        PrintSuccess(2)

Outputs
        Fail         Success         2


    Sub PrintSuccess(e As Enum2)
        Console.WriteLine(e.ToString())
    End Sub

No comments:

Post a Comment