C#中enum是值类型,用于定义命名常量,默认底层类型为int;支持显式赋值、自定义底层类型、[Flags]位运算、安全转换(TryParse)、字符串序列化及数据库存储建议。

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最安全:返回bool表示是否成功,不抛异常 -
Enum.IsDefined只检查值是否存在,但对字符串不敏感大小写(默认),且无法识别带空格或连字符的别名 - 避免用
(MyEnum)someInt强转——若someInt不在枚举范围内,不会报错,但值非法,后续逻辑易出错
string input = "Completed"; if (Enum.TryParse(input, true, out Status result)) { Console.WriteLine(result); // 输出 Completed } else { Console.WriteLine("无效状态"); }
使用 [Flags] 特性实现位运算组合
当枚举需要表示「多个状态同时存在」(比如权限、选项集合),应加 [Flags] 特性,并确保值是 2 的幂次(1, 2, 4, 8…)。否则 .ToString() 和 Enum.ToString() 无法正确解析组合值。
小型企业入门套件(The Small Business Starter Kit)提供了一个商业宣传网站的完整演示,他适合中小型企业。使用他创建的网站支持自定义模板,具有先进的功能,包括:内容和数据管理的SQL和XML数据源整合。该源码包含C#和VB两个版本,只有前台部分源码,微软官方截止到51aspx发布源码时还没有提供后台代码。小型企业网站入门套件的关键页面包括:产品分类显示新闻发布显示商户认证
- 未加
[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
}
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 温床。最稳妥的做法是:定义即冻结、传输即字符串、日志即名称、数据库字段加注释说明取值含义。









