枚举(Enumeration,简称 Enum )是 C# 中一种值类型,用于表示一组固定的、具有明确含义的常量集合。
简单来说:
枚举 = 给一组整数值起有意义的名字
例如:
不用枚举:
int status = 1;
if (status == 1)
{
Console.WriteLine("运行中");
}
问题:
- 1 代表什么?别人不知道
- 代码可读性差
- 容易写错
使用枚举:
cs
Status status = Status.Running;
if (status == Status.Running)
{
Console.WriteLine("运行中");
}
代码更加清晰。
一、枚举的基本语法
1. 定义枚举
语法:
enum 枚举名
{
成员1,
成员2,
成员3
}
示例:
cs
enum WeekDay
{
Monday,
Tuesday,
Wednesday,
Thursday,
Friday,
Saturday,
Sunday
}
使用:
cs
WeekDay today = WeekDay.Monday;
Console.WriteLine(today);
输出:
Monday
二、枚举底层原理
枚举本质上是整数类型。
例如:
cs
enum Color
{
Red,
Green,
Blue
}
编译后类似:
Red = 0
Green = 1
Blue = 2
默认从 0 开始递增。
等价于:
Console.WriteLine((int)Color.Red);
输出:
0
三、指定枚举值
可以手动指定值:
cs
enum ErrorCode
{
Success = 200,
NotFound = 404,
ServerError = 500
}
使用:
int code = (int)ErrorCode.NotFound;
Console.WriteLine(code);
输出:
404
四、枚举值可以重复
例如:
cs
enum Status
{
OK = 1,
Success = 1,
Failed = 2
}
这里:
Status.OK
和:
Status.Success
实际上都是:
1
允许存在。
五、枚举的类型转换
1. 枚举转整数
显式转换:
cs
enum Level
{
Low = 1,
Medium = 2,
High = 3
}
Level level = Level.High;
int value = (int)level;
Console.WriteLine(value);
输出:
3
2. 整数转枚举
cs
int value = 2;
Level level = (Level)value;
Console.WriteLine(level);
输出:
Medium
注意:
如果数字不存在:
cs
Level level = (Level)100;
Console.WriteLine(level);
输出:
100
不会报错。
所以转换前最好检查:
cs
if(Enum.IsDefined(typeof(Level),100))
{
Level level=(Level)100;
}
六、枚举与字符串转换
1. 枚举转字符串
cs
Level level = Level.High;
string text = level.ToString();
Console.WriteLine(text);
输出:
High
2. 字符串转枚举
cs
string text = "Medium";
Level level = Enum.Parse<Level>(text);
Console.WriteLine(level);
输出:
Medium
如果字符串可能错误:
cs
string text="AAA";
if(Enum.TryParse(text,out Level level))
{
Console.WriteLine(level);
}
else
{
Console.WriteLine("无效值");
}
七、枚举遍历
使用:
cs
foreach(Level item in Enum.GetValues(typeof(Level)))
{
Console.WriteLine(item);
}
输出:
Low
Medium
High
八、枚举判断
例如:
cs
enum UserRole
{
Guest,
User,
Admin
}
判断:
cs
UserRole role = UserRole.Admin;
if(role == UserRole.Admin)
{
Console.WriteLine("管理员");
}
九、Flags 枚举(位枚举)
这是 C# 枚举非常重要的高级用法。
普通枚举:
cs
enum Permission
{
Read,
Write,
Delete
}
只能表示一种状态。
例如:
用户同时拥有:
读取 + 写入
怎么办?
使用 Flags。
1. 定义 Flags 枚举
cs
[Flags]
enum Permission
{
None = 0,
Read = 1,
Write = 2,
Delete = 4
}
这里使用二进制:
cs
Read 0001
Write 0010
Delete 0100
2. 组合权限
cs
Permission userPermission =
Permission.Read |
Permission.Write;
结果:
0011
表示:
读取 + 写入
3. 判断权限
cs
if((userPermission & Permission.Read)
== Permission.Read)
{
Console.WriteLine("有读取权限");
}
4. 添加权限
userPermission |= Permission.Delete;
5. 删除权限
userPermission &= ~Permission.Write;
十、枚举作为 switch 条件
枚举最常见用途:
cs
enum Operation
{
Add,
Subtract,
Multiply
}
Operation op = Operation.Add;
switch(op)
{
case Operation.Add:
Console.WriteLine("加法");
break;
case Operation.Subtract:
Console.WriteLine("减法");
break;
case Operation.Multiply:
Console.WriteLine("乘法");
break;
}
十一、枚举在类中的使用
例如:
cs
class Player
{
public string Name {get;set;}
public PlayerState State {get;set;}
}
enum PlayerState
{
Idle,
Running,
Dead
}
使用:
Player p = new Player();
p.Name="Tom";
p.State=PlayerState.Running;
十二、枚举与数据库设计
常见场景:
用户状态:
enum UserStatus
{
Normal=1,
Disabled=2,
Deleted=3
}
数据库:
| Id | Status |
|---|---|
| 1 | 1 |
| 2 | 2 |
代码:
UserStatus status =
(UserStatus)reader["Status"];
优点:
数据库存数字:
1
2
3
代码显示:
Normal
Disabled
Deleted
十三、枚举常用方法
Enum.GetName()
获取名称:
cs
string name =
Enum.GetName(typeof(Level),2);
Console.WriteLine(name);
输出:
Medium
Enum.IsDefined()
判断是否存在:
bool result =
Enum.IsDefined(typeof(Level),3);
Enum.GetValues()
获取所有值:
Array values =
Enum.GetValues(typeof(Level));
Enum.GetNames()
获取所有名称:
string[] names =
Enum.GetNames(typeof(Level));
十四、枚举最佳实践
1. 使用复数命名(推荐)
推荐:
enum Colors
{
}
或者:
cs
enum UserStatus
{
}
不推荐:
enum ColorType
{
}
2. 明确指定业务值
不要:
cs
enum Status
{
Normal,
Disabled
}
因为以后添加成员可能改变编号。
推荐:
cs
enum Status
{
Normal = 1,
Disabled = 2
}
3. Flags 必须使用 2 的幂
正确:
cs
Read=1
Write=2
Delete=4
错误:
cs
Read=1
Write=2
Delete=3
因为:
3 = 1+2
会产生冲突。
十五、枚举和常量的区别
| const | enum | |
|---|---|---|
| 用途 | 单个常量 | 多个相关常量 |
| 类型 | 任意 | 整数类型 |
| 可读性 | 一般 | 高 |
| 组合 | 不方便 | 支持Flags |
例如:
常量:
const int Red=1;
const int Green=2;
枚举:
cs
enum Color
{
Red,
Green
}
明显枚举更适合。
十六、实际项目案例
订单状态:
cs
public enum OrderStatus
{
Created = 1,
Paid = 2,
Shipping = 3,
Completed = 4,
Cancelled = 5
}
订单类:
cs
public class Order
{
public int Id {get;set;}
public OrderStatus Status {get;set;}
}
业务:
cs
Order order=new Order();
order.Status=OrderStatus.Paid;
if(order.Status==OrderStatus.Paid)
{
Console.WriteLine("订单已支付");
}
比:
if(status==2)
安全和易读很多。
总结
C# Enum 核心知识:
| 知识点 | 说明 |
|---|---|
| enum | 定义枚举 |
| 默认值 | 从0开始 |
| 底层 | 整数类型 |
| 转换 | 强制转换 |
| Parse | 字符串转枚举 |
| TryParse | 安全转换 |
| Flags | 多选状态 |
| switch | 状态判断 |
| 数据库 | 状态字段最佳选择 |
一句话总结:
枚举就是把一组有固定含义的数字,包装成可读、可维护、安全的类型,是 C# 中表示状态、权限、分类最常用的数据结构之一。