EKsumic's Blog

let today = new Beginning();

Click the left button to use the catalog.

OR

C#枚举类型

什么是枚举?

枚举是一个特殊的值类型,它可以让你指定一组命名的数值常量。

public enum BorderSide{Left,Right,Top,Bottom}

 

枚举类型基本上是int且会自动赋值,从0,1,2,3 . . .

 

也可以是byte:

public enum BorderSide:byte{Left,Right,Top,Bottom}

而且还可以指定:

public enum BorderSide:byte{Left=1,Right=2,Top=10,Bottom=11}

这种写法等同于:

public enum BorderSide:byte{Left=1,Right,Top=10,Bottom}

 

枚举显式转换int值,反过来也是显式转换:

int i=(int)BorderSide.Left;
BorderSide side=(BorderSide) i;
bool leftOrRight=(int)side<=2;

 

有一个特例0,不需要显式转换:

BorderSide b=0;
if(b==0) . . . 


FLAGS ENUM

可以对枚举的成员进行组合
为了避免歧义,枚举成员需要显式地赋值,典型的就是使用2的乘幂

[Flags]
public enum BorderSides{None=0,Left=1,Right=2,Top=4,Bottom=8}

flags enum,可以使用位操作符,例如|和&

namespace 枚举
{
    [Flags]
    public enum BorderSides { None = 0, Left = 1, Right = 2, Top = 4, Bottom = 8 }
    class Program
    {
        static void Main(string[] args)
        {
            // 按位或
            // 00000001
            // 00000010
            // -----------
            // 00000011

            BorderSides leftRight = BorderSides.Left | BorderSides.Right;
            // 按位与
            // 00000011
            // 00000001
            // -----------
            // 00000001

            if ((leftRight & BorderSides.Left) != 0)
            {
                Console.WriteLine("Includes Left");
            }

            string formatted = leftRight.ToString();  // "Left,Right"

            BorderSides s = BorderSides.Left;
            s |= BorderSides.Right;
            Console.WriteLine(s == leftRight);  // True

            // 按位异或
            // 00000011
            // 00000010
            // -----------
            // 00000001

            s ^= BorderSides.Right;
            Console.WriteLine(s); // Left
        }
    }
}

输出:

Includes Left
True
Left


FLAGS属性

▢ 按约定,如果枚举成员可组合的话,flags属性就应该应用在枚举类型上。
    ▢ 如果声明了这样的枚举,却没有使用flags属性,你仍然可以组合枚举的成员,但是调用枚举实例的ToString()方法时,输出的将是一个数值而不是一组名称。
▢ 举例:

namespace Flags属性
{
    class Program
    {
        [Flags]
        public enum BorderSides {
            Top= 1, 
            Right = 2,
            Bottom = 4,
            Left = 8 }
        static void Main(string[] args)
        {
            // 00000001
            // 00000010
            // 00000100
            // -----------
            // 00000111

            var b = BorderSides.Top | BorderSides.Right | BorderSides.Bottom;
            Console.WriteLine(b);
        }
    }
}

输出:

Top, Right, Bottom

如果没[Flags]:

7

 

 

▢ 按约定,可组合枚举的名称应该是复数的。[比如BorderSides]

▢ 在声明可组合枚举的时候,可以直接使用组合的枚举成员作为成员:

[Flags]
public enum BorderSides
{
    None=0,
    Left=1,Right=2,Top=4,Bottom=8,
    LeftRight=Left|Right;
    TopBottom=Top|Bottom,
    All=LeftRight|TopBottom
}

 

枚举支持的操作符:
= == != < > <= >= + - ^ & | ~ += -= ++ -- sizeof
▲ 其中按位的、比较的、算术的操作符返回的都是处理底层值后得到的结果 
▲ 加法操作符只允许1个枚举和1个整形数值相加,两个枚举相加是不可以的


类型安全的问题

public enum BorderSide{Left,Right,Top,Bottom}

BorderSide b=(BorderSide)12345;
Console.WriteLine(b);    //12345

BorderSide b=BorderSide.Bottom;
b++;      //No errors

虽然以上代码不会报错,但是违背了枚举类型的初衷。

所以我们有

检查枚举类型的合理性:Enum.IsDefined()静态方法

BorderSide side=(BorderSide)12345;
Console.WriteLine(Enum.IsDefined(typeof(BorderSide),side));  //False


什么是嵌套类型

▢ 嵌套类型就是声明在另一个类型作用范围内的类型

比如:

public class TopLevel
{
    public class Nested{}       // Nested class
    public enum Color{Red,Blue,Tan}    // Nested enum 
}

 

嵌套类型的特性

▢ 可访问封闭类型的私有成员,以及任何封闭类型能访问的东西
▢ 可以使用所有的访问修饰符来声明,不仅仅是public和internal
▢ 嵌套类型的默认访问级别是private而不是internal
▢ 从封闭类型外边访问嵌套类型需要使用到封闭类型的名称

 

This article was last edited at 2020-03-17 03:24:47

* *