编写高质量代码改善C#程序的157个建议——建议110:用类来代替enum

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了编写高质量代码改善C#程序的157个建议——建议110:用类来代替enum相关的知识,希望对你有一定的参考价值。

 

建议110:用类来代替enum

枚举(enum)用来表示一组固定的值。例如,为了表示星期信息,我们可以定义枚举Week:

    enum Week
    {
        Monday,
        Tuesday,
        Wednesday,
        Thursday,
        Friday,
        Saturday,
        Sunday
    }

枚举最大的优点在于它的类型是值类型。相比较引用类型来说,它可以在关键算法中提升性能,因为它不需要创建在“堆”中。但是,如果不考虑这方面的因素,我们不妨让类(引用类型)来代替枚举。代码如下:

        class Week
        {
            public static readonly Week Monday = new Week(0);
            public static readonly Week Tuesday = new Week(1);
            //省略

            private int _infoType;

            private Week(int infoType)
            {
                _infoType = infoType;
            }
        }

我们将类型Week的构造方法实现为private,这有效阻止了类型在外部生成类的实例,使它的行为更接近于枚举。

类Week相比枚举Week的优点在于,它能够添加方法或重写基类方法,以便提供丰富的功能。以星期为例,如果要提供更有意义的字符串,如指定Monday是星期一,对于枚举来说,这并不是天然支持的。甚至会大费周折。曾经有人实现过枚举的这种功能:

    enum Week
    {
        [EnumDescription("星期一")]
        Monday,
        [EnumDescription("星期二")]
        Tuesday
    }

    [AttributeUsage(AttributeTargets.Field, AllowMultiple = false)]
    public sealed class EnumDescriptionAttribute : Attribute
    {
        private string description;
        public string Description
        {
            get { return this.description; }
        }

        public EnumDescriptionAttribute(string description)
            : base()
        {
            this.description = description;
        }
    }
    public static class EnumHelper
    {
        public static string GetDescription(Enum value)
        {
            if (value == null)
            {
                throw new ArgumentNullException("value");
            }
            string description = value.ToString();
            FieldInfo fieldInfo = value.GetType().GetField(description);
            EnumDescriptionAttribute[] attributes = (EnumDescriptionAttribute[])fieldInfo.GetCustomAttributes(typeof(EnumDescriptionAttribute), false);
            if (attributes != null && attributes.Length > 0)
            {
                description = attributes[0].Description;
            }
            return description;
        }
    }


        static void Main(string[] args)
        {
            Console.WriteLine(EnumHelper.GetDescription(Week.Monday));
        }

输出:

星期一

 

如果不为枚举元素加上属性EnumDescription特性,我们只能使用:

Console.WriteLine(EnumHelper.GetDescription(Week.Monday));

输出:

Monday

如果在类中,就不会有枚举的这种不方便了,因为可以通过重写object的ToString方法将问题解决。代码如下:

        static void Main(string[] args)
        {
            Console.WriteLine(Week.Monday);
        }

        class Week
        {
            public static readonly Week Monday = new Week(0);
            public static readonly Week Tuesday = new Week(1);
            //省略

            private int _infoType;

            private Week(int infoType)
            {
                _infoType = infoType;
            }

            public override string ToString()
            {
                switch (_infoType)
                {
                    case 0:
                        return "星期一";
                    case 1:
                        return "星期二";
                    default:
                        throw new Exception("不正确的星期信息!");
                }
            }
        }

相比枚举而言,类能赋予类型更多的行为。当然,如果应用场合满足如下特性,我们就应该更多的考虑使用枚举:

  • 效率。这源于枚举是值类型。
  • 类型用于内部,不需要增加更多的行为属性。
  • 类型元素不需要提供附加的特性。

 

 

 

转自:《编写高质量代码改善C#程序的157个建议》陆敏技

以上是关于编写高质量代码改善C#程序的157个建议——建议110:用类来代替enum的主要内容,如果未能解决你的问题,请参考以下文章

编写高质量代码改善C#程序的157个建议——建议141:不知道该不该用大括号时,就用

编写高质量代码改善C#程序的157个建议——建议52:及时释放资源

编写高质量代码改善C#程序的157个建议——建议41:实现标准的事件模型

编写高质量代码改善C#程序的157个建议——建议67:慎用自定义异常

编写高质量代码改善C#程序的157个建议——建议111:避免双向耦合

编写高质量代码改善C#程序的157个建议——建议143:方法抽象级别应在同一层次