C# 枚举类型使用方法 C#如何定义和使用enum

来源:这里教程网 时间:2026-02-21 17:40:10 作者:

enum 基本定义和语法结构

在 C# 中,

enum
是一种值类型,用于定义一组命名的常量。它本质是整数(默认
int
),但语义更清晰、可读性更强。

定义时必须指定名称,成员默认从 0 开始递增;也可显式赋值,支持跳号、重复值(不推荐):

public enum Status
{
    Pending = 0,
    Processing = 1,
    Completed = 2,
    Failed = -1  // 可跨类型赋值,如负数或大整数
}
枚举底层类型可以是
sbyte
byte
short
ushort
int
(默认)、
uint
long
ulong
,声明时用冒号指定:
enum Priority : byte { Low, Medium, High }
枚举成员名必须是合法标识符,不能带空格或特殊字符;若需显示“User ID”,应配合
[Display]
[Description]
特性处理
不要在枚举里写方法或字段——
enum
不支持继承、不能有实例构造函数,也不是类

如何安全地将字符串或数字转为 enum

运行时解析用户输入(如 API 参数、配置文件)时,常见需求是把

string
int
转成对应枚举值。直接强制转换可能抛出异常,必须校验。

Enum.TryParse<t></t>
最安全:返回
bool
表示是否成功,不抛异常
Enum.IsDefined
只检查值是否存在,但对字符串不敏感大小写(默认),且无法识别带空格或连字符的别名
避免用
(MyEnum)someInt
强转——若
someInt
不在枚举范围内,不会报错,但值非法,后续逻辑易出错
string input = "Completed";
if (Enum.TryParse<Status>(input, true, out Status result))
{
    Console.WriteLine(result); // 输出 Completed
}
else
{
    Console.WriteLine("无效状态");
}

使用 [Flags] 特性实现位运算组合

当枚举需要表示「多个状态同时存在」(比如权限、选项集合),应加

[Flags]
特性,并确保值是 2 的幂次(1, 2, 4, 8…)。否则
.ToString()
Enum.ToString()
无法正确解析组合值。

未加
[Flags]
时,
Permission.Read | Permission.Write
的结果调用
.ToString()
会输出数字(如
"3"
),而非
"Read, Write"
每个成员值必须唯一且为 2 的幂;可使用十六进制(
0x10
)或左移(
1 )提升可读性
判断是否包含某标志用
HasFlag
(.NET Core 2.0+ 推荐用
(value & flag) == flag
,性能更好)
[Flags]
public enum Permission
{
    None = 0,
    Read = 1,
    Write = 2,
    Execute = 4,
    All = Read | Write | Execute
}
<p>Permission userPerm = Permission.Read | Permission.Write;
Console.WriteLine(userPerm); // 输出 "Read, Write"

序列化与反序列化注意事项

JSON 序列化(如 System.Text.Json 或 Newtonsoft.Json)默认按枚举数值序列化,不是名称。这容易引发前后端协作问题:前端看到数字 1,却不知道对应哪个状态。

System.Text.Json:用
JsonSerializerOptions.Converters.Add(new JsonStringEnumConverter())
改为字符串序列化
Newtonsoft.Json:全局设置
JsonConvert.DefaultSettings = () => new JsonSerializerSettings { Converters = { new StringEnumConverter() } };
数据库存储建议存字符串(提高可读性、避免迁移风险),若存整数,务必确保枚举定义稳定——增删成员或改顺序会导致历史数据含义错乱 ASP.NET Core API 默认用 System.Text.Json,不加转换器时,
enum
字段响应体是数字,前端需硬编码映射,非常脆弱

枚举本身轻量,但它的语义边界一旦被跨层(如 DB → DTO → UI)模糊处理,就容易变成隐性 bug 温床。最稳妥的做法是:定义即冻结、传输即字符串、日志即名称、数据库字段加注释说明取值含义。

相关推荐