为什么Enum.Parse会创建未定义的条目?
class Program { static void Main(string[] args) { string value = "12345"; Type enumType = typeof(Fruits); Fruits fruit = Fruits.Apple; try { fruit = (Fruits) Enum.Parse(enumType, value); } catch (ArgumentException) { Console.WriteLine(String.Format("{0} is no healthy food.", value)); } Console.WriteLine(String.Format("You should eat at least one {0} per day.", fruit)); Console.ReadKey(); } public enum Fruits { Apple, Banana, Orange } }
如果您执行上面的代码,结果显示:
你应该每天至少吃一个12345。
我真的希望在传递未知名称(字符串)时抛出ArgumentException。 仔细查看Enum.Parse定义可以看出:
摘要:
将一个或多个枚举常量的名称或数值的字符串表示forms转换为等效的枚举对象。例外:
ArgumentException :enumType不是枚举。 – 或 – 值是空字符串或仅包含空格。 – 或 – value是一个名称,但不是为枚举定义的命名常量之一 。
即,如果传递整数的字符串表示,则创建新的枚举值,并且现在设计引发exception。 这有意义吗?
至少我现在知道在Enum.IsDefined(enumType, value)
之前调用Enum.IsDefined(enumType, value)
Enum.Parse()
“命名常量”是Enum值的文本表示,而不是您分配给它的数字。
如果你改变:
string value = "12345";
至:
string value = "Cake";
您将看到您期望的错误,因为“value是一个名称,但不是为枚举定义的命名常量之一。”。 在这种情况下,您传入的值是名称“Cake”,但不是枚举中的名称。
想想Enum.Parse(enumType, value);
执行以下操作:
- 如果
value
是空引用,则抛出ArgumentNullException - 值中的
value
是enumType
中枚举中指定常量之一。 如果是,则从枚举中返回该值并停止。 - 值中的
value
直接转换为基础类型(在本例中为Int32),如果是,则返回该值并停止( 即使该值没有命名常量 )。 - 值中的
value
直接转换为基础类型,但在基础类型的范围之外? 例如,该值是一个包含大于MAXINT的数字的字符串。 如果是,则抛出OverflowException
。 - 值是否不能转换为基础类型? 如果是,抛出ArgumentException。
枚举可以是其基本整数类型的任何值。 它不仅限于命名常量。
例如,以下内容完全有效:
enum Foo{ A, B, C, D } Foo x = (Foo)5;
尽管5不对应于命名常量,但它仍然是Foo
的有效值,因为Foo
的基础类型是Int32
。
如果要调用x.ToString()
,返回的值将只是“5”,因为没有命名常量与x的值相对应。
Enum.Parse()
是Enum.Parse()
的逆函数。 您应该期望Enum.ToString()
可以返回Enum.Parse()
可以接受的任何内容。 例如,这包括标志枚举的逗号分隔值:
[Flags] enum Foo{ A = 1, B = 2, C = 4, D = 8 } Foo x = Foo.A | Foo.B | Foo.C | Foo.D; int i = (int)x; string s = x.ToString(); Console.WriteLine(i); Console.WriteLine(s); Console.WriteLine((Foo)Enum.Parse(typeof(Foo), i.ToString()) == x); Console.WriteLine((Foo)Enum.Parse(typeof(Foo), s) == x);
输出:
15 A B C D 真正 真正
编辑:
你真正想要的是这样的:
static Enum GetEnumValue(Type enumType, string name){ // null-checking omitted for brevity int index = Array.IndexOf(Enum.GetNames(enumType), name); if(index < 0) throw new ArgumentException(""" + name + "" is not a value in " + enumType, "name"); return Enum.GetValues(enumType).GetValue(index); }
或不区分大小写的版本:
static Enum GetEnumValue(Type enumType, string name, bool ignoreCase){ // null-checking omitted int index; if(ignoreCase) index = Array.FindIndex(Enum.GetNames(enumType), s => string.Compare(s, name, StringComparison.OrdinalIgnoreCase) == 0); // or StringComparison.CurrentCultureIgnoreCase or something if you // need to support fancy Unicode names else index = Array.IndexOf(Enum.GetNames(enumType), name); if(index < 0) throw new ArgumentException(""" + name + "" is not a value in " + enumType, "name"); return Enum.GetValues(enumType).GetValue(index); }
你需要使用Enum.IsDefined:
https://msdn.microsoft.com/en-us/library/essfb559.aspx
using System; [Flags] enum Colors { None=0, Red = 1, Green = 2, Blue = 4 }; public class Example { public static void Main() { string[] colorStrings = { "0", "2", "8", "blue", "Blue", "Yellow", "Red, Green" }; foreach (string colorString in colorStrings) { try { Colors colorValue = (Colors) Enum.Parse(typeof(Colors), colorString); if (Enum.IsDefined(typeof(Colors), colorValue) | colorValue.ToString().Contains(",")) Console.WriteLine("Converted '{0}' to {1}.", colorString, colorValue.ToString()); else Console.WriteLine("{0} is not an underlying value of the Colors enumeration.", colorString); } catch (ArgumentException) { Console.WriteLine("'{0}' is not a member of the Colors enumeration.", colorString); } } } } // The example displays the following output: // Converted '0' to None. // Converted '2' to Green. // 8 is not an underlying value of the Colors enumeration. // 'blue' is not a member of the Colors enumeration. // Converted 'Blue' to Blue. // 'Yellow' is not a member of the Colors enumeration. // Converted 'Red, Green' to Red, Green.
我个人认为很遗憾Enum.Parse
接受数字的字符串表示。 如果您正在寻找替代方案,您可能需要查看我的Unconstrained Melody项目,该项目具有各种解析选项,并且也是强类型的。
您当然可以将Enum.IsDefined
与解析结合使用。 你肯定想接受字符串版本的数字吗? 或者你真的只期待免费精选名字大全?
上述就是C#学习教程:为什么Enum.Parse会创建未定义的条目?分享的全部内容,如果对大家有所用处且需要了解更多关于C#学习教程,希望大家多多关注---计算机技术网(www.ctvol.com)!
本文来自网络收集,不代表计算机技术网立场,如涉及侵权请联系管理员删除。
ctvol管理联系方式QQ:251552304
本文章地址:https://www.ctvol.com/cdevelopment/1015106.html