代码之家  ›  专栏  ›  技术社区  ›  Sebastian Good

为什么C 3允许文本零(0)隐式转换为任何枚举?

  •  9
  • Sebastian Good  · 技术社区  · 15 年前

    C 3(Visual Studio 2008)对语言进行了突破性的更改。( http://msdn.microsoft.com/en-us/library/cc713578.aspx ,请参见更改12),它允许将任何文本零隐式转换为枚举。这在很多方面似乎很奇怪。有人知道为什么这是规范的一部分吗?为什么不是字面上的呢?还是七?为什么零特殊?它做出了一些非常违反直觉的过载分辨率选择。例如。

    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"
    

    非常混乱,故意引入了一种破坏性的语言变化。有什么想法吗?

    5 回复  |  直到 15 年前
        1
  •  10
  •   JaredPar    15 年前

    C始终允许将文本0隐式转换为任何枚举值。改变的是规则如何应用于其他常量表达式。它被设置为更加一致,并允许计算结果为0的任何常量表达式隐式转换为枚举。

    您给出的示例在所有版本的C中产生相同的行为。

    以下是更改行为的示例(直接从 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输出:

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

    Visual C 2008输出:

    0 => A(Enum E)
    (int) E.Zero => A(Enum E)
        2
  •  4
  •   joshperry    15 年前

    我想这是因为0被认为是枚举的“默认值”。

    C(C 2.0中引入了默认关键字)

    enum DbType {
        Unspecified,
        SqlServer
    }
    
    DbType t;
    int i = 0;
    
    Console.WriteLine(t == i);
    Console.WriteLine(i == default(DbType));
    

    输出:

    True
    True
    
        3
  •  2
  •   leppie    15 年前

    从1.0版开始就允许这样做。它是枚举的默认值。

    “文本0是隐式可转换的 任何枚举类型。在Visual C 2005中 以及早期版本的编译器, 还有一些常数 计算为0的表达式 无法隐式转换为任何枚举 类型,但确定 这些表达式中的哪些是 敞篷车还不清楚。在Visual C中 2008年,所有常量表达式 等于0可以隐式 已转换为任何枚举类型。“

        4
  •  0
  •   Dan Diplo    15 年前

    “枚举元素的默认基础类型为int。默认情况下,第一个枚举器的值为0,并且每个后续枚举器的值增加1。”—这是从 MSDN notes for 1.1 framework 所以一直都是这样。

        5
  •  0
  •   Wayne Hartman    15 年前

    正如其他人提到的,0是默认枚举。试着把枚举想象成如下(以更明确的方式):

    public enum HairColor
    {
        Blonde           = 0x0000;
        Brunett          = 0x0001;
        Red              = 0x0002;
        StrawberryBlonde = 0x0004;
    }
    

    由于您在给定枚举的值中不是显式的,C将自动为其指定默认值。如果您不想这样做,那么您必须明确定义给定枚举的值。