用户选择枚举范围之外的值时出现问题



我希望用户能够键入一个选项,并让程序将他们的选择与其中一个enum选项相匹配。我把它设置在一个循环中,这样用户就可以在条目不匹配的情况下继续尝试(即AppleBananaCarrots)。

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.");
}

最新更新