我希望用户能够键入一个选项,并让程序将他们的选择与其中一个enum
选项相匹配。我把它设置在一个循环中,这样用户就可以在条目不匹配的情况下继续尝试(即Apple
、Banana
、Carrots
)。
enum Food {Apple, Banana, Carrot};
Food foodChoice;
while (!(Enum.TryParse<Food>(Console.ReadLine(), true, out foodChoice)))
{
Console.WriteLine("Not a valid choice.");
}
这一切都很顺利,直到用户输入,比如5
。显然,Food
枚举没有那么多选项,TryParse
仍然会输出true
,将foodChoice
赋值为5。有没有一个简单的方法来处理这个问题?
尝试使用Enum.IsDefined
方法:
Food foodChoice;
while (!Enum.TryParse(Console.ReadLine(), true, out foodChoice)
|| !Enum.IsDefined(typeof(Food), foodChoice))
{
Console.WriteLine("Not a valid choice.");
}
根据MSDN关于TryParse
:的这种特殊(有点奇怪)行为
请注意,此值不必是
TEnum
枚举的成员。。。如果value是不表示TEnum枚举的基础值的整数的字符串表示,则该方法返回一个枚举成员,其基础值是转换为整数类型的值。如果这种行为不可取,请调用IsDefined
方法以确保整数的特定字符串表示实际上是TEnum
的成员。
因此,除了解析字符串值之外,您还需要通过调用IsDefined
来检查该值是否真的存在:
!Enum.IsDefined(typeof(Food), foodChoice)
现在对于为什么?整数始终被视为有效的枚举值。它不检查实际值,因为它需要计算枚举值的每个可能组合。这是真的,因为这是一个有效的枚举值:
Food foodChoice = Food.Carrot|Food.Apple|Food.Banana;
在这种情况下,只有几个可能的值,而5的值是不可能的。对于更长的枚举,计算可能会变得巨大。这就是为什么他们在解析步骤中省略了它。
看看这个:
var x = Enum.GetValues(typeof(Food));
var a = Enum.IsDefined(typeof(Food), "Apple");
var b = Enum.IsDefined(typeof(Food), "2");
var c = Enum.IsDefined(typeof(Food), 2);
var d = Enum.IsDefined(typeof(Food), 4);
var e = Enum.GetNames(typeof(Food)).Contains("Apple");
var f = Enum.GetNames(typeof(Food)).Contains("2");
//var f = Enum.GetNames(typeof(Food)).Contains(2); //won't compile...
一种方法是查看字符串是否包含整数。
Food foodChoice;
int n;
string temp;
while (!(Enum.TryParse<Food>(temp = Console.ReadLine(), true, out foodChoice)) || int.TryParse(temp,out n))
{
Console.WriteLine("Not a valid choice.");
}