C#教程 - 枚举类型(Enum Type)
更新记录
转载请注明出处:https://www.cnblogs.com/cqpanda/p/16690865.html
2022年9月16日 发布。
2022年9月10日 从笔记迁移到博客。
枚举类型(Enum Type)说明
枚举只有一种成员:命名的整型常量的集合
枚举是值类型
使用枚举有效地防止用户提供无效值,使代码更加清晰
定义枚举
注意:
枚举成员不可以使用修饰符
每个枚举成员底层都是一个常量值
默认情况下,枚举成员的类型是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
}
使用枚举
说明:枚举变量的内容本质是数值
带标志位的Enum类型(Flags Enums)
使用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();
}
}
}
枚举支持的运算符(Enum Operators)
= == != < > <= >= + - ^ & | ~
+= -= ++ -- sizeof
注意:
按位、算术和比较运算符返回处理基础整数值的结果
允许在枚举和集成类型之间进行加法运算,但不能在两个枚举之间进行加法运算
.NET中的枚举
.NET Enum类型中还可以使用一些有用的静态方法:
GetName方法以枚举类型对象和整数为参数,返回枚举成员名称
GetNames方法以枚举类型对象为参数,返回枚举中所有成员的名称
类型安全问题(Type-Safety Issues)
因为枚举可以在其基础整型类型之间进行转换
所以它的实际值可能超出合法枚举成员的界限
在实际的代码中需要为未知的枚举值做额外的处理 或者 检测值是否存在
实例:超出界限的转换
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
枚举转换(Enum Conversions)
枚举类型 与 数值类型转换
将枚举类型 与 整型类型转换 直接使用强制转换即可
实例:
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类型自带静态方法
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;
}
}
Enum中静态方法
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();
}
}
}
本文来自博客园,作者:重庆熊猫,转载请注明原文链接:https://www.cnblogs.com/cqpanda/p/16690865.html