C#枚举

  • 值类型

  • 设置底层类型和显式值

    • enum Enum : ulong {	// 类似继承的方式设置底层类型,默认为int
          Green,			// 0
          Yellow = 10, 	// 10
          Red, 			// 11
      }
      
    • 每个枚举类型都有一个底层值,默认为int,第一个成员默认为0,后面比前面多1

    • 如果给其中某个成员赋值,则再后面没有显式赋值的成员会继续在前面的基础上+1

    • 如果显式值过大超出了int的范围,可以设置底层类型为long或者ulong,底层类型可以是任何整数类型

    • 关联到成员名称的值不需要是独特的,如可以允许多个成员使用同样的值

    • 也可以使用该枚举类型中的成员给其他成员赋值

  • 位标志

    • 标志变量的压缩,把多个标志变量压缩到同一个变量里表示,类似C++中的 bitset?

    • 可以通过或运算|来标志多个位

    • 可以通过HasFlag判断该位是否被标记,如果是多个位可以对要判断的位相或

    • 也可以通过&来判断标记

    • [Flags]	// Flags特性
      enum FlagsEnum {
          first = 0x01,
          second = 0x02,
          third = 0x04,
          forth = 0x08
      }
          FlagsEnum flags = FlagsEnum.second | FlagsEnum.third;
          bool f1 = flags.HasFlag(FlagsEnum.second);
          bool f2 = flags.HasFlag(FlagsEnum.first | FlagsEnum.third);	// 注意逻辑,虽然后面是两个条件的相或,但是HasFlag本身是和与逻辑对应的,所以是两个标志位都检查的
          bool f3 = ((flags & FlagsEnum.forth) == FlagsEnum.forth);
      
    • Flags特性

      • 虽然不改变计算结果,但是提供了一些方便的特性
      • 首先是通知编译器、对象浏览器等,该枚举可以按位标志进行组合
      • 其次是格式化输出
        • 我们知道对于枚举类型,直接输出和ToString()均为返回字符串
        • 但是对于上面代码中的flags这种经过或运算的值,如果不加Flags特性时输出为计算后的整数,因为在调用ToString时没有找到值为12对应的枚举成员的字符串,所以会输出整数12
        • 加上Flags特性后,会将12对应两个分开的位标志成员,输出为两个字符串并用逗号和空格隔开
  • 补充

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

    • 不同枚举类型之间不能比较大小

    • 枚举类型可以枚举

      • enum MyEnum {
            first, second, third
        }
        for (MyEnum e = MyEnum.first; e <= MyEnum.third; e++) {
            System.Console.WriteLine(e);
        }
        
      • 但是注意上面这段代码,如果在枚举声明时有赋值操作,则在遍历时会有中间没有声明的整数被枚举到

    • Enum类型还包含一些静态方法,如GetNames、GetName、IsDefine等,多数都有泛型与非泛型两种使用方式,但是泛型的版本,如果有第二个参数的话必须是枚举,非泛型版本可以使用整数或字符串

      • GetNames:参数为枚举的类型(Type),返回所有成员名称的字符串数组,泛型版本无参数

      • string[] myEnums = Enum.GetNames(typeof(MyEnum));	// 也可以使用Enum.GetNames<MyEnum>()
        foreach (var myEnum in myEnums) {
            System.Console.WriteLine(myEnum);
        }
        
      • GetName:参数为枚举的类型(Type)和整数,返回成员名称的字符串,如果不存在则返回null

      • IsDefined:参数为枚举的类型(Type)和整数或字符串,如果在枚举中定义了该项则返回true