6

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

 1 year ago
source link: https://www.cnblogs.com/aoximin/p/16907638.html
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client

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

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

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

enum ConnectionState 
{
	DisConnected,
	Connecting,
	Connected,
	DisConnecting
}

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

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

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

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

1289794-20221120111943515-1713584278.png

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

1289794-20221120112306570-1769942583.png

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

1289794-20221120112231129-543873866.png

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

1289794-20221120112725984-1170809552.png

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

1289794-20221120112800314-1382591155.png

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

1289794-20221120113113295-71442440.png

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

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

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

1289794-20221120113859585-1122472332.png

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

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

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

比如:
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的时候:
1289794-20221120120925358-76957314.png

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

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

1289794-20221120121220882-1110219860.png

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

1289794-20221120121443921-1103278376.png

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);
	}
}

该系列继续更新。


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK