更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16690865.html
2022年9月16日 发布。
2022年9月10日 从笔记迁移到博客。
枚举只有一种成员:命名的整型常量的集合
枚举是值类型
使用枚举有效地防止用户提供无效值,使代码更加清晰
注意:
枚举成员不可以使用修饰符
每个枚举成员底层都是一个常量值
默认情况下,枚举成员的类型是int
默认情况下,编译器把第一个成员赋值为0,后一个成员在前一个成员基础上加1
自定义枚举成员类型:
实例:定义enum类型底下的类型
public enum BorderSide : byte { Left, Right, Top, Bottom }
实例:定义enum类型每个值的具体数值
public enum BorderSide : byte { Left=1, Right=2, Top=10, Bottom=11 }
实例:定义enum类型,值来自其他enum类型
public enum HorizontalAlignment { Left = BorderSide.Left, Right = BorderSide.Right, Center }
实例:定义Enum类型,值来自自身
[Flags] enum BorderSides { None=0, Left=1, Right=1<<1, Top=1<<2, Bottom=1<<3, LeftRight = Left | Right, TopBottom = Top | Bottom, All = LeftRight | TopBottom }
说明:枚举变量的内容本质是数值
使用Flags特性修饰enum类型即可
说明:在一个数据单元上存储多个条件状态
实现:
使用[Flag]修饰枚举
各个成员值内存表示
一个枚举值拥有多个条件
使用时直接使用hasFlag方法判断即可
还可以判断多个条件
在新版本的C#中可以使用二进制字面量与位标志枚举结合使用
注意:使用Byte类型
[System.Flags] public enum WondersOfTheAncientWorld: byte { None = 0b_0000_0000, // i.e. 0 GreatPyramidOfGiza = 0b_0000_0001, // i.e. 1 HangingGardensOfBabylon = 0b_0000_0010, // i.e. 2 StatueOfZeusAtOlympia = 0b_0000_0100, // i.e. 4 TempleOfArtemisAtEphesus = 0b_0000_1000, // i.e. 8 MausoleumAtHalicarnassus = 0b_0001_0000, // i.e. 16 ColossusOfRhodes = 0b_0010_0000, // i.e. 32 LighthouseOfAlexandria = 0b_0100_0000 // i.e. 64 }
实例:带标志位的Enum类型
[Flags] enum BorderSides { None=0, Left=1, Right=2, Top=4, Bottom=8 }
实例:检测标志位是否存在
using System; namespace ConsoleApp2 { /// <summary> /// 测试使用的Enum类型 /// </summary> [Flags] public enum Direction { Top, Bottom, Left, Right, } class Program { static void Main(string[] args) { //多个值整合在一起 Direction direction = Direction.Bottom & Direction.Right; //检测标志位 if(direction.HasFlag(Direction.Bottom)) { Console.WriteLine("Direction = Left+Top"); } //wait Console.ReadKey(); } } }
= == != < > <= >= + - ^ & | ~
+= -= ++ -- sizeof
注意:
按位、算术和比较运算符返回处理基础整数值的结果
允许在枚举和集成类型之间进行加法运算,但不能在两个枚举之间进行加法运算
.NET Enum类型中还可以使用一些有用的静态方法:
GetName方法以枚举类型对象和整数为参数,返回枚举成员名称
GetNames方法以枚举类型对象为参数,返回枚举中所有成员的名称
因为枚举可以在其基础整型类型之间进行转换
所以它的实际值可能超出合法枚举成员的界限
在实际的代码中需要为未知的枚举值做额外的处理 或者 检测值是否存在
实例:超出界限的转换
BorderSide b = (BorderSide) 12345; Console.WriteLine (b); // 12345
实例:位运算和算数运算同样会导致问题
BorderSide b = BorderSide.Bottom; b++; // No errors
实例:处理可能未知的枚举值
void Draw (BorderSide side) { if (side == BorderSide.Left) {...} else if (side == BorderSide.Right) {...} else if (side == BorderSide.Top) {...} else {...} // Assume BorderSide.Bottom }
实例:检测enum值是否存在
使用Enum.IsDefined静态方法
注意:Enum.IsDefined静态方法对Flags Enum不起作用
BorderSide side = (BorderSide) 12345; Console.WriteLine (Enum.IsDefined (typeof (BorderSide), side)); // False
将枚举类型 与 整型类型转换 直接使用强制转换即可
实例:
using System; namespace ConsoleApp1 { /// <summary> /// 定义测试使用的枚举类型 /// </summary> enum Color { Red, Green, Pink, Blue } class Program { static void Main(string[] args) { //转为整数类型 int i = (int)Color.Red; Console.WriteLine(i); //0 Color color = (Color)2; Console.WriteLine(color); //Pink //wait Console.ReadKey(); } } }
实例:枚举与数值类型转换
int i = (int) BorderSide.Left; BorderSide side = (BorderSide) i;
实例:enum类型之间转换,本质是转为底层数值类型再进行准换
HorizontalAlignment h = (HorizontalAlignment) BorderSide.Right; // same as: HorizontalAlignment h = (HorizontalAlignment) (int) BorderSide.Right;
字符串转为Enum类型:使用Enum.Parse 或者Enum.TryParse
实例:使用Enum.Parse
using System; namespace ConsoleApp1 { enum PandaOption { Option1, Option2, Option3 } class Program { static void Main(string[] args) { string userInput = "Option1"; PandaOption pandaOption; try { pandaOption = (PandaOption)Enum.Parse(typeof(PandaOption), userInput); } catch (ArgumentException e) { pandaOption = PandaOption.Option1; } Console.WriteLine(pandaOption); Console.ReadKey(); } } }
实例:使用Enum.TryParse
using System; namespace ConsoleApp1 { /// <summary> /// 定义测试使用的枚举类型 /// </summary> enum Color { Red, Green, Pink, Blue } class Program { static void Main(string[] args) { //转为字符串类型 Console.WriteLine(Color.Red); //Red //转为枚举类型 object result; Enum.TryParse(typeof(Color), "Blue", out result); if(result != null) { Console.WriteLine((Color)result); //Blue } //wait Console.ReadKey(); } } }
Enum类型转为字符串
string? name = Enum.GetName(typeof(Direction), 0); Console.WriteLine(name);
获得Enum类型的所有元素的字符串
string[] names = Enum.GetNames(typeof(Direction)); foreach (var item in names) { Console.WriteLine(item); }
获得Enum类型的所有元素的数值
int[] values = (int[])Enum.GetValues(typeof(Direction)); foreach (var item in values) { Console.WriteLine(item); }
必要时在枚举类型中定义一个表示空的成员 None = 0
在旧代码中为了兼容的考虑,不要删除枚举的旧成,确保代码的向后兼容性
避免使用枚举类型表示不完成类型的,比如版本号这种日后会进行修改的部分
避免创建保留给未来使用的枚举值,这样可以减少代码的BUG
避免枚举类型只包含一种单一的值
使用枚举值代替布尔值可以有效提高代码可读性
实例:
public enum LightSatus { Unknow, On, Off, } public void LightDoing(LightSatus lightSatus) { switch (lightSatus) { case LightSatus.Unknow: break; case LightSatus.On: break; case LightSatus.Off: break; default: break; } }
GetName可以获得枚举指定成员的字符串名称
GetNames可以获得枚举全部成员字符串组成的数组
实例:使用GetName 和 使用GetNames
using System; namespace ConsoleApp3 { enum Direction { Up, Down, Left, Right } class Program { static void Main(string[] args) { //获得指定值对应的字符串 string v = Enum.GetName(typeof(Direction), 0); Console.WriteLine(v); //获得枚举类型中全部的的成员字符串 string[] v2 = Enum.GetNames(typeof(Direction)); foreach (string item in v2) { Console.WriteLine(item); } //wait Console.ReadKey(); } } }