重学c#系列——枚举[二十三]

前言

该系列继续更新,枚举介绍。

正文

首先呢,枚举是值类型,这个没什么好说的。

enum ConnectionState 
{
    DisConnected,
    Connecting,
    Connected,
    DisConnecting
}

如果不显示命名的情况下呢?第一个DisConnected为0,Connecting 为1。

enum ConnectionState 
{
    DisConnected,
    Connecting=100,
    Connected,
    DisConnecting
}

如果Connecting 被设置为100了,那么connected 就是101,DisConnecting 就是102。

枚举支持不同类型之间的枚举转换,但是两种的值要相等。

重学c#系列——枚举[二十三]插图

但是数组并不能直接转换:

重学c#系列——枚举[二十三]插图1

先转换成array,然后再转换成ConnectionState2 是可以的:

重学c#系列——枚举[二十三]插图2

数字转枚举,一般就是之间显示转换就可以了。

重学c#系列——枚举[二十三]插图3

即使这个值不存在,转换也不会存在问题:

重学c#系列——枚举[二十三]插图4

这个时候a.tostring()就是100,不然的话就会输出我们定义的字符串了。

重学c#系列——枚举[二十三]插图5

那么如果将字符串转换为枚举呢?

internal class Program
{
    static void Main(string[] args)
    {
        if (Enum.TryParse("DisConnected", out ConnectionState value))
        {
            Console.WriteLine(value.ToString());
        }
        Console.ReadKey();
    }
}

如果用parse,那么如果字符串没有和枚举匹配的那么会报错。

重学c#系列——枚举[二十三]插图6

然后枚举还有一个比较好的功能那就是可以多选。

这种情况就是枚举作为标志位使用。

其实原理很简单,利用的是二进制这个设计。

比如:
000000000000000001
000000000000000010
那么他们相加之后就是:000000000000000011

这个只要知道哪一个位数上有,那么哪个就被选中了。

官方使用比较多的例子是system.io 中:

[Flags]
public enum FileAttributes
{
    ReadOnly = 0x0001,
    Hidden = 0x0002,
    System = 0x0004,
    Directory = 0x0010,
    Archive = 0x0020,
    Device = 0x0040,
    Normal = 0x0080,
    Temporary = 0x0100,
    SparseFile = 0x0200,
    ReparsePoint = 0x0400,
    Compressed = 0x0800,
    Offline = 0x1000,
    NotContentIndexed = 0x2000,
    Encrypted = 0x4000,
    IntegrityStream = 0x8000,
    NoScrubData = 0x20000
}

这里面就有很多组合,比如ReadOnly 和Hidde 等等,这里就不举例了。

static void Main(string[] args)
{
    FileInfo fileInfo = new FileInfo("c:/test.txt");
    fileInfo.Attributes = FileAttributes.Hidden| FileAttributes.ReadOnly;
    Console.ReadKey();
}

上面就是说明将这个文件信息设置为隐藏且只读的吧。| 符合为:如果存在于任一操作数中,二进制 OR 运算符复制一位到结果中。

当然,如果有一些组合你已经知道了,那么你可以在枚举中就处理:

[Flags]
enum MyEnum
{
    high = 1,
    rich = 2,
    graceful = 4,
    hrq = high | rich | graceful
}

然后很多人建议在flags 中都有一个none 为0的枚举,表示一个都没有选:

[Flags]
enum MyEnum
{
    none = 0,
    high = 1,
    rich = 2,
    graceful = 4,
    hrq = high | rich | graceful
}

然后这里解释一下,我们为什么要使用Flags。

我们知道原理后,其实不使用flags也是可以实现的。

enum MyEnum
{
    none = 0,
    high = 1,
    rich = 2,
    graceful = 4,
    hrq = high | rich | graceful
}

那么这个flags 给我们带来了什么呢?

static void Main(string[] args)
{
    var test = MyEnum.high | MyEnum.rich;
    Console.WriteLine(test.ToString());
}

当我们tostring的时候:
重学c#系列——枚举[二十三]插图7

给我们返回了high, rich,如果没有这个flags的话,那么返回的是3。

那么可以string 用逗号可以转换为,如果没有flags,那么就转换不了:

重学c#系列——枚举[二十三]插图8

因为enum 根据enum 走的是不同的方法:

重学c#系列——枚举[二十三]插图9

private static string? InternalFormat(RuntimeType enumType, ulong value)
{
    EnumInfo enumInfo = GetEnumInfo(enumType);

    if (!enumInfo.HasFlagsAttribute)
    {
        return GetEnumName(enumInfo, value);
    }
    else // These are flags OR'ed together (We treat everything as unsigned types)
    {
        return InternalFlagsFormat(enumType, enumInfo, value);
    }
}

该系列继续更新。

文章来源于互联网:重学c#系列——枚举[二十三]

THE END
分享
二维码