最近我发现,仅包含数字字符的任何字符串都可以转换为C#中的枚举。例如,假设有一个定义如下的枚举:
public enum TestEnum
{
One = 1,
Two = 2,
Three = 3
};
我可以将一些随机数字字符串转换为TestEnum
。
TestEnum testEnum = (TestEnum)Enum.Parse(typeof(TestEnum), "4");
Console.WriteLine(testEnum);
当然不会将值'4'映射到已定义的TestEnum
值中,并且输出仅为4
,但是不会出错,因此此转换是合法的。 / p>
另一方面,如果我尝试检查此值是否在TestEnum
中定义:
Console.WriteLine(Enum.IsDefined(typeof(TestEnum), "4"));
我会在输出中收到False
。
考虑到以下非数字字符串的转换,这对我来说有点奇怪
(TestEnum)Enum.Parse(typeof(TestEnum), "Test")
将抛出System.ArgumentException
。
我对这种行为感到困惑。它是故意设计的还是只是巧合?
答案 0 :(得分:3)
它是故意设计的还是只是巧合?
我不确定我是否理解你的问题。 The documentation在我看来似乎很清楚:
将一个或多个枚举常量的名称或数值的字符串表示形式转换为等效的枚举对象。
(强调我的)
它也说:
如果value是不表示enumType枚举的基础值的整数的字符串表示形式,则该方法返回一个枚举成员,该枚举成员的基础值已转换为整数类型。如果这种行为是不受欢迎的,请调用IsDefined方法以确保整数的特定字符串表示形式实际上是enumType的成员
很明显,这是故意的行为,而不仅仅是偶然的。
请注意,您始终可以将enum
的基础类型(在这种情况下为int
)的任何值强制转换为enum
类型本身。 enum
类型的功能不会强制enum
的值对应于命名值。因此,解析行为与enum
类型的编译时行为完全一致。
我想有人可能会争论enum
类型是否应允许使用未命名的值。但是,考虑到enum
类型的功能之一是允许基于标志的枚举,不管它们是否具有[Flags]
属性,并且给它带来不便(至少可以说)必须命名enum
类型中定义的每个标志的每个组合,似乎合理的做法是它们可以继续并允许所有enum
类型的类型使用未命名的值。