C# 枚举 简单介绍和问题解决
代码参考C#7.0本质论
介绍枚举的定义、初始化、调用(包含我遇到的一些问题以及自己解决的方案,有更好的代码欢迎分享)
enum 枚举名称:枚举类型(int,...)
{
枚举值1,
枚举值2
}
//位标志枚举
[Flags] 修饰符 enum 枚举名称(使用复数形式最好):枚举类型(int,...)
{
枚举值1=1<<0,
枚举值2=1<<1,
...
}
枚举是一组命名常量,其基础类型为任何整型类型。 如果未显式声明基础类型, 默认Int32(可以是处char之外的任意整型) 。
枚举值之间以逗号分隔,最后定义的枚举值结尾不需要加逗号。
枚举值实际作为整数常量实现,默认第一个枚举值是0,后续每一项递增1。但可以显式的为枚举赋值。
显式赋值实例如下:
enum ConnectionState
{
Disconnected,
Connecting=10,
Connected,
Disconnecting
}
//Disconnected=0,Connecting=10,Connected=11,Disconnecting=12
Disconnected仍然默认赋值为0,Connecting显示赋值为10,后面的枚举值自动递增1。
位标志枚举名称通常是复数,因为他的值代表一个标志的集合。主要作为标志使用,增强可读性。
继续使用刚刚在上面定义的枚举
ConnectionState connectedState=new ConnectionState();
这样调用枚举时相当于
ConnectionState connectedState=ConnectionState.Disconnected;
输出显示(直接调用Console.WriteLine();方法会返回枚举值的字符串表示,需要显示转换成对应的值):
Console.WriteLine(ConnectionState1.Disconnected);
Console.WriteLine((int)(ConnectionState1.Disconnected));
//Disconnected
//0
若是枚举中没有任何一个值为0,将等效于
ConnectionState connectedState=(ConnectionState)0;
//OR
ConnectionState connectedState=0;
此时枚举变量connectedState成为非预定义值,这里展现了枚举的一个特点。即枚举值为已知值提供了名称,同时允许在运行时分配未知的值。但是编码时必须谨慎,要考虑兼容等问题。
所以定义枚举时最好定义一个0值。
对位标志枚举:
[Flags]enum ThreadPriorityLevel
{
Idle=2,
busy=8
}
调用
ThreadPriorityLevel priority1 = (ThreadPriorityLevel)Enum.Parse(typeof(ThreadPriorityLevel), "Idle,busy");
Console.WriteLine("the priority value is {0:D} combined entries of {0}", priority1);
//the priority value is 10 combined entries of Idle,busy
注意若是没有位标志[Flags],则会输出the priority value is 10 combined entries of 10
非位标志枚举也可用此方法调用,或者使用Tostring方法调用返回枚举值字符串表示形式
connectionState = (ConnectionState)Enum.Parse(typeof(ConnectionState), Console.ReadLine());
Console.WriteLine(connectionState1.ToString());
这部分我曾今在CSDN中提过问题,没有得到很好的解决,欢迎分享自己的代码
比较整数switch和枚举switch
枚举switch可读性会更好,两者在运行时的性能完全一样
int connectionState1;
switch (connectionState)
{
case 0:
Console.WriteLine("Display 0");
break;
case 1:
Console.WriteLine("Display 1");
break;
case 2:
Console.WriteLine("Display 2");
break;
case 3:
Console.WriteLine("Display 3");
break;
}
ConnectionState2 connectionState2;
switch (connectionState2)
{
case ConnectionState1.connected:
Console.WriteLine(ConnectionState1.connected);
break;
case ConnectionState1.Connecting:
Console.WriteLine(ConnectionState1.Connecting);
break;
case ConnectionState1.Disconnected:
Console.WriteLine(ConnectionState1.Disconnected);
break;
case ConnectionState1.Disconnecting:
Console.WriteLine(ConnectionState1.Disconnecting);
break;
}
在这里我为了达到一些效果做一个比较
在整数switch中我加入了
Console.Write("Enter the connectionState:");
connectionState1 = int.Parse(Console.ReadLine());
在枚举switch中加入了
connectionState2 = (ConnectionState1)Enum.Parse(typeof(ConnectionState1), Console.ReadLine());
此时两个代码输入整数可输出对应的Console.WriteLine();语句,枚举switch输入枚举值名称字符串也会输出对应Console.WriteLine();语句(当然这里最好再加一些提示语之类的,避免输入不存在的值抛出异常)
一些规范的补充:避免包含单个值的枚举,要为简单枚举提供值0来代表无。若不是初始化,0就是默认值。可以在类中声明,但是不能再方法中声明。
C#不支持不同枚举数组之间的转型。但CLR允许。
不同枚举之间的兼容性,利用了CLR的复制兼容性比C#宽松,但并不一定代表在不同CLR实现中都能发挥作用。
代码来自C#7.0本质论
ConnectionState1[] states = (ConnectionState1[])(Array)new ConnectionState2[42];
欢迎大家指错补充。