Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does C# 3 allow the implicit conversion of literal zero (0) to any Enum?

Tags:

c#

c#-3.0

C#3 (Visual Studio 2008) introduced a breaking change to the language (http://msdn.microsoft.com/en-us/library/cc713578.aspx, see change 12) that allows any literal zero to be implicitly converted to an Enum. This seems odd in many ways. Does anyone know why this is part of the spec? Why not a literal one? Or seven? Why is zero special? And it makes some very counterintuitive overload resolution choices. For instance.

function string F(object o) { return o.ToString(); }
function string F(DbType t) { return t.ToString(); }
int i = 0;
F((long)0) == "String" // would have been "0" in VS 2005
F(0) == "String"
F(i) == "0"

Very confusing, and an intentionally introduced breaking change to the language. Any ideas?

like image 760
Sebastian Good Avatar asked Oct 27 '09 19:10

Sebastian Good


2 Answers

C# has always allowed the implicit conversion of the literal 0 to any Enum value. What has changed is how the rule is applied to other constant expressions. It was made to be more consistent and allow any constant expressions which evaluates to 0 to be implicitly convertible to an enum.

The example you gave produces the same behavior in all versions of C#.

Here is an example of changed behavior (directly from the linked documentation)

public enum E
{
    Zero = 0,
    One = 1,
} 

class A
{
    public static A(string s, object o)
    { System.Console.WriteLine("{0} => A(object)", s); } 

    public static A(string s, E e)
    { System.Console.WriteLine("{0} => A(Enum E)", s); }

    static void Main()
    {
        A a1 = new A("0", 0);
        A a3 = new A("(int) E.Zero", (int) E.Zero);
    }
}

Visual C# 2005 output:

0 => A(Enum E)
(int) E.Zero => A(object)

Visual C# 2008 output:

0 => A(Enum E)
(int) E.Zero => A(Enum E)
like image 88
JaredPar Avatar answered Oct 29 '22 21:10

JaredPar


I would guess that it is because 0 is considered the "Default Value" of enums.

C# (default keyword was introduced in C# 2.0)

enum DbType {
    Unspecified,
    SqlServer
}

DbType t;
int i = 0;

Console.WriteLine(t == i);
Console.WriteLine(i == default(DbType));

Outputs:

True
True
like image 40
joshperry Avatar answered Oct 29 '22 20:10

joshperry