Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Console.WriteLine(Enum.Value) gives different output in C# and VB.Net

Tags:

c#

enums

vb.net

I am basically a C# guy, but writing VB.Net code these days.

Today I came across a very different behaviour of .Net

C# Code

enum Color
{
   Red,
   Green,
   Blue
}

class Demo
{
    public static void Main()
    {
        System.Console.WriteLine(Color.Red);
    }
}

This prints Red

But when this code is written in VB.Net it prints 0.

VB.Net Code

Module Module1

    Sub Main()
        System.Console.WriteLine(Color.Red)
    End Sub

End Module

Enum Color
    Red
    Green
    Blue
End Enum

Why so different?

like image 630
Nikhil Agrawal Avatar asked Dec 19 '22 00:12

Nikhil Agrawal


1 Answers

There is no Console.WriteLine(Enum) overload so the compilers are forced to pick one of the other ones. Overload resolution rules are very arcane and the VB.NET and C# rules are not the same, but both compilers are willing to pick one when there's an implicit conversion to the target argument type and pick the one that takes the least amount of work.

Which is where another rule applies, this kind of statement in VB.NET is perfectly valid:

   Dim example As Integer = Color.Red  '' Fine

But the C# compiler spits at:

   int example = Color.Red;            // CS0266

Insisting that you apply an (int) cast. It only has an explicit conversion, not an implicit one like VB.NET.

So the C# compiler is going to ignore all the overloads that take an integral argument, none are candidates because only explicit conversions exist for them. Except one, the Console.WriteLine(Object) overload. There is an implicit conversion for that one, it takes a boxing conversion.

The VB.NET compiler sees it as well, but now the "better" conversion comes into play. A boxing conversion is a very expensive conversion, converting to Integer is very cheap. It requires no extra code. So it likes that one better.

Workarounds are simple:

    System.Console.WriteLine(CObj(Color.Red))         '' or
    System.Console.WriteLine(Color.Red.ToString())
like image 151
Hans Passant Avatar answered May 15 '23 08:05

Hans Passant