zoukankan      html  css  js  c++  java
  • 枚举Enum和常量0之间的恩怨

    1,任何为0的常量表达式都能隐式的转换成枚举Enum。

    对于这一点,在程序中没少吃苦头。特别是对于函数重载的情况,往往让人一头雾水。

    看看下面的代码(摘自MSDN),你能猜到输出吗?

    public enum E
    {
        Zero = 0,
        One = 1,
    } 
    
    class A
    {
        public A(string s, object o)
        { System.Console.WriteLine("{0} => A(object)", s); } 
    
        public A(string s, E e)
        { System.Console.WriteLine("{0} => A(Enum E)", s); }
    } 
    
    class B
    {
        static void Main()
        {
            A a1 = new A("0", 0);
            A a2 = new A("1", 1);
            A a3 = new A("(int) E.Zero", (int) E.Zero);
            A a4 = new A("(int) E.One", (int) E.One);
        }
    }
    Visual C# 2005 output:
    0 => A(Enum E)
    1 => A(object)
    (int) E.Zero => A(object)
    (int) E.One => A(object)
    
    Visual C# 2008 output:
    0 => A(Enum E)
    1 => A(object)
    (int) E.Zero => A(Enum E)
    (int) E.One => A(object)

    自VS2008起,所有能确定为0的常量表达式都能隐式的转换成Enum。

    所以如果不想要这种隐式的转换的话,在程序中处理0时,就需要转换。

    再来看看我的测试例子:

    namespace WZTEST
    {
        public partial class Form1 : Form
        {
            public Form1()
            {
                InitializeComponent();
            }
    
            public void SqlParameter(string parameterName, object value)
            {
                //object
            }
    
            public void SqlParameter(string parameterName, SqlDbTypeA dbType)
            {
                //Enum
            }
    
            private void button1_Click(object sender, EventArgs e)
            {
                const int ZERO = 0;
                SqlParameter("aa", 0);
                SqlParameter("aa", (int)0);
                SqlParameter("aa", ZERO);
                SqlParameter("aa", Convert.ToInt32(0));
            }
        }
    
        public enum SqlDbTypeA
        {
            Int = 1
        }
    }

    我们来反编译下button1_Click函数,看看编译器都做了什么。

    private void button1_Click(object sender, EventArgs e)
    {
        this.SqlParameter("aa", (SqlDbTypeA) 0);
        this.SqlParameter("aa", (SqlDbTypeA) 0);
        this.SqlParameter("aa", (SqlDbTypeA) 0);
        this.SqlParameter("aa", Convert.ToInt32(0));
    }

    傻眼了吧!前面三个全部变成了Enum。好吧,既然斗不过微软,那就只有接受这个结果。

    结论:对于有Enum的重载函数,传入0时,最好用Convert转换;或者用一个变量赋值0后再传入函数,以避开万恶的编译器规则。

    备注:微软这样做的原因是Enum和0之间的比较比较频繁,为了方便开发者,就做了这样的隐式转换;但却给函数重载留下隐患,稍不小心就会犯错。

  • 相关阅读:
    TOJ 假题之 Cow Brainiacs
    TOJ 2596: Music Notes
    Wannafly模拟赛2
    2017 ACM-ICPC 亚洲区(乌鲁木齐赛区)网络赛
    2017 ACM/ICPC Asia Regional Shenyang Online
    北京师范大学第十五届ACM决赛-重现赛
    Codeforces Round #433 (Div. 2, based on Olympiad of Metropolises)
    Codeforces Round #432 (Div. 2, based on IndiaHacks Final Round 2017)
    LibreOJ β Round #4
    长沙理工大学第十二届ACM大赛-重现赛
  • 原文地址:https://www.cnblogs.com/xiashengwang/p/3449618.html
Copyright © 2011-2022 走看看