枚举(Enum)

枚举是由程序员定义的类型,与类或结构一样。

●与结构一样,枚举是值类型,因此直接存储它们的数据,而不是分开存储成引用和数据。

●枚举只有一种类型的成员:命名的整数值常量。


每个枚举类型都有一个底层整数类型,默认是int。

●每个枚举成员都被赋予一个底层类型的常量值。

●在默认情况下,编译器把第一个成员赋值为0,并对每一个后续成员赋值比前一个成员赋值多1。

 enum TrafficLight
    {
        Green,
        Yellow,
        Red
    }
    class Program
    {
        static void Main(string[] args)
        {


            TrafficLight t1 = TrafficLight.Green;
            TrafficLight t2 = TrafficLight.Yellow;
            TrafficLight t3 = TrafficLight.Red;
            TrafficLight t4 = t3;


            Console.WriteLine("{0},\t{1}", t1, (int)t1);
            Console.WriteLine("{0},\t{1}", t2, (int)t2);
            Console.WriteLine("{0},\t{1}", t3, (int)t3);
            Console.ReadKey();
        }

    }

设置底层类型和显式值

可以把冒号和类型名放在枚举名之后,这样就可以使用int以外的整数类型, 类型可以是任何整数类型。所有成员常量都属于枚举底层类型。


成员常量的值可以是底层类型的任何值。要显示地设置一个成员的值,在枚举声明值的变量名之后使用初始化表达式,尽管不能有重复的名称,但是可以有重复的值:

  enum TrafficLight
    {
        Green=10,
        Yellow=15,
        Red=15

    }




隐式成员编号

一下显示地赋值给任何成员常量。如果不初始化一个成员常量,编译器隐式地给它赋一个值。

●关联到成员名称的值不需要时独特的。


位标志

使用单个字的不同位作为表示一组开/关标志的紧凑方法将其称为标志宇

步骤:

(1)确定需要多少个位标志,并选择一种有足够多位的无符号类型来保存它。

(2)确定每个位位置代表什么,并给它们一个名词,声明一个选中的整数类型的枚举,每个成员由一个位位置表示。

(3)使用按位或(or)运算符设置保持该为标志的字中的适当的位。

(4)使用按位与(and)运算符,或HasFlag方法解开位标志。


要创建一个带有适当的位标志的字,需要声明一个该枚举类型的变量,并使用按位或运算符设置需要的位。


要判断标志字是否包含特定的位标志集,可以使用枚举类型中的HasFlag布尔方法。在标志字上调用HasFlag方法,并将要检查的位标志作为参数。如果设置了指定的位标志,HasFlag返回true,否则返回false。


HasFlag方法还可以检测多个位标志。


使用按位与运算符


Flags特性

语法:

[Flags]

enum CardDeckSettings:uint{

....

}

Flag特性不会改变计算结果,但却提供了一些方便的特性。

(1)通知编译器、对象浏览器以及其他查看这段代码的工具,该枚举的成员不仅可以用做单独的值。还可以按位标志进行组合。这样浏览器就可以更恰当地解释该枚举的变量。

(2)允许枚举的ToString方法为位标志的值提供更多的格式化信息。ToString方法以一个枚举值为参数,将其与枚举的常量成员相比较。如果与某个成员相匹配,ToString方法返回该成员的字符串名称。

 [Flags]
    enum CardDeckSettings : uint
    {
        SingleDeck = 0x01,
        LargePictures = 0x02,
        FancyNumbers = 0x04,
        Animation = 0x08
    }
    class Program
    {


        static void Main(string[] args)
        {
            CardDeckSettings ops;
            ops = CardDeckSettings.FancyNumbers;//设置一个标志
            Console.WriteLine(ops.ToString());


            ops = CardDeckSettings.FancyNumbers | CardDeckSettings.Animation;//设置两个标志
            Console.WriteLine(ops.ToString());


            Console.ReadKey();
        }

    }

使用位标志的示例

 [Flags]
    enum CardDeckSettings : uint
    {
        SingleDeck = 0x01,
        LargePictures = 0x02,
        FancyNumbers = 0x04,
        Animation = 0x08
    }


    class MyClass
    {
        bool UseSingleDeck = false;
        bool UserBigPics = false;
        bool UserFancyNumbers = false;
        bool UserAnimation = false;
        bool UserAnimationFancyNumbers = false;




        public void SetOptions(CardDeckSettings ops)
        {
            UseSingleDeck = ops.HasFlag(CardDeckSettings.SingleDeck);
            UserBigPics = ops.HasFlag(CardDeckSettings.LargePictures);
            UserFancyNumbers = ops.HasFlag(CardDeckSettings.FancyNumbers);
            UserAnimation = ops.HasFlag(CardDeckSettings.Animation);


            CardDeckSettings testFlags = CardDeckSettings.Animation | CardDeckSettings.FancyNumbers;
            UserAnimationFancyNumbers = ops.HasFlag(testFlags);
        }


        public void PrintOption()
        {
            Console.WriteLine("Option settings:");
            Console.WriteLine(" Use Single Deck    -{0}", UseSingleDeck);
            Console.WriteLine(" Use Large Pictures  -{0}", UserBigPics);
            Console.WriteLine(" User Fancy Numbers  -{0}", UserFancyNumbers);
            Console.WriteLine(" Show Animation  -{0}", UserAnimation);
            Console.WriteLine(" Show Animation and FancyNumbers -{0}", UserAnimationFancyNumbers);
        }
    }




    class Program
    {
        static void Main(string[] args)
        {
            MyClass mc = new MyClass();
            CardDeckSettings ops = CardDeckSettings.SingleDeck | CardDeckSettings.FancyNumbers | CardDeckSettings.Animation;
            mc.SetOptions(ops);
            mc.PrintOption();
            Console.ReadKey();
        }

    }

关于枚举的补充

枚举只有单一的成员类型:声明的成员常量。

●不能对成员使用修饰符。它们都隐式地具有和枚举相同的可访问性。

●由于成员是常量,即使在每月该枚举类型的变量时它们也可以访问。使用枚举类型名,跟着一个点和成员名。


 ●枚举是一个独特的类型。比较不同枚举类型的成员会导致编译时的错误。

enum FirstEnum
    {
        Mem1,
        Mem2
    }


    enum SecondEnum
    {
        Mem1,
        Mem2
    }


    class Program
    {
        static void Main(string[] args)
        {
            if (FirstEnum.Mem1 < FirstEnum.Mem2)//正确,相同的枚举类型
            {
                Console.WriteLine("True");
            }


            //if (FirstEnum.Mem1 < SecondEnum.Mem1)//错误,不同的枚举类型
            //{
            //    Console.WriteLine("True");
            //}


            Console.ReadKey();
        }

    }


.NET enum类型 (enum就是基于该类型)还包括了一些有用的静态方法:

●GetName方法以枚举类型对象和整数位参数,返回响应的枚举成员的名称;

●GetNames方法以枚举类型对象为参数,返回该枚举中所有成员的全部名称。

 enum TrafficLight
    {
        Green,
        Yello,
        Red
    }




    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Second member of TrafficLight is {0} \n", Enum.GetName(typeof(TrafficLight), 1));
            foreach (var name in Enum.GetNames(typeof(TrafficLight)))
            {
                Console.WriteLine(name);
            }
            Console.ReadKey();
        }
    }

猜你喜欢

转载自blog.csdn.net/luochenlong/article/details/80476012