为何C#的Enum.TryParse解析"-1"会成功?枚举无该值却返回true
关于Enum.TryParse解析未定义枚举数值返回成功的疑问
我希望仅当枚举解析成功时才打印其值。根据Enum.TryParse()文档说明:该方法用于将枚举常量的名称或数值的字符串表示转换为等效的枚举对象,返回值表示转换是否成功。我原本认为只有解析TestEnum中定义的名称(如"first")或数值(如"1")时才会成功,但解析字符串"-1"时,调用仍成功并返回值-1,这是为什么?
示例代码
using System; public class HelloWorld { public enum TestEnum { first = 0, second = 1, third = 2 } public static void Main(string[] args) { TestEnum testEnum; bool res; res = Enum.TryParse("first", out testEnum); if (res) Console.WriteLine ("TEST 1 - res: " + res.ToString() + ", value: " + testEnum.ToString()); res = Enum.TryParse("third", out testEnum); if (res) Console.WriteLine ("TEST 2 - res: " + res.ToString() + ", value: " + testEnum.ToString()); res = Enum.TryParse("1", out testEnum); if (res) Console.WriteLine ("TEST 3 - res: " + res.ToString() + ", value: " + testEnum.ToString()); res = Enum.TryParse("-1", out testEnum); if (res) Console.WriteLine ("TEST 4 - res: " + res.ToString() + ", value: " + testEnum.ToString()); res = Enum.TryParse("fourth", out testEnum); if (res) Console.WriteLine ("TEST 5 - res: " + res.ToString() + ", value: " + testEnum.ToString()); } }
输出结果
TEST 1 - res: True, value: first TEST 2 - res: True, value: third TEST 3 - res: True, value: second TEST 4 - res: True, value: -1 // <-- 为什么会成功?
原因解析
默认情况下,Enum.TryParse()的执行逻辑是:
- 优先尝试匹配枚举的成员名称,匹配成功则返回true;
- 若名称不匹配,会尝试将字符串解析为枚举的基础数值类型(默认是
int)——只要字符串能被解析为该基础类型的有效值,不管这个数值是否在枚举的定义成员中,方法都会返回true,并将该数值赋值给枚举变量。
"-1"属于有效的int类型数值,因此Enum.TryParse()返回true,同时把枚举变量的值设为-1。
解决方案:仅允许解析枚举已定义成员
如果你希望只有当字符串对应枚举中已定义的成员时才判定为解析成功,有两种实现方式:
方式1:解析后验证(兼容所有.NET版本)
在Enum.TryParse()返回true后,额外调用Enum.IsDefined()方法验证该值是否为枚举的已定义成员:
res = Enum.TryParse("-1", out testEnum); // 仅当解析成功且值为枚举已定义成员时才执行后续逻辑 if (res && Enum.IsDefined(typeof(TestEnum), testEnum)) Console.WriteLine ("TEST 4 - res: " + res.ToString() + ", value: " + testEnum.ToString());
方式2:使用Strict解析选项(.NET 7+)
在.NET 7及以上版本,可以使用带ParseOptions的重载,指定Enum.ParseOptions.Strict,强制只允许解析枚举已定义的成员:
res = Enum.TryParse<TestEnum>("-1", Enum.ParseOptions.Strict, out testEnum); if (res) Console.WriteLine ("TEST 4 - res: " + res.ToString() + ", value: " + testEnum.ToString());
此时解析"-1"会返回false,不会触发后续打印逻辑。
内容的提问来源于stack exchange,提问作者mikyll98
相关产品推荐
相关产品推荐

