使用转到大小写(变量);在 C# 开关中

本文关键字:开关 变量 大小写 | 更新日期: 2023-09-27 18:34:51

我正在为 Visual Studio C# 控制台中的一门课程编写文本冒险,并决定使用 switch 语句而不是 if-else 链,因为 goto case 非常有用(到目前为止它已经非常有效(。我知道开关本身中的每个情况都必须是一个常量,但我想知道这是否也适用于使用 goto 案例。例如,我有:

switch (location)
{
case 1:
  break;
case 2:
  break;
case 3:
  break;
//I have 10 cases, each representing a location such as "Orc Cave", I just cut it down for brevity
default:
  break;
}

我希望能够输入一个整数变量,然后转到该整数,我有以下方法可以完成此操作:

string travel2 = Console.ReadLine();//inputs a integer representing each location
int travel2A = Convert.ToInt32(travel2);
if (1<=travel2A && travel2A<=10)
{
    goto case(travel2A);
}
else{
    goto case(2);//current location
}

一切正常,但有一个"预期恒定值"警告在案例(travel2A(下。是否可以通过一些调整使goto大小写输入成为变量,或者这只是switch语句的限制?如果是后者,我可以做一个 if-else 链,但在我看来,输入一个变量更方便。非常感谢对此的任何帮助!谢谢!

使用转到大小写(变量);在 C# 开关中

普通goto的标签需要在源代码中拼写出来。它们不是经过计算的表达式;它们只是标识符goto case的标签必须是常量表达式,在编译时计算,而不是在运行时计算。

我会提醒您不要使用任何严重依赖任何形式的"goto"的解决方案。对任何类型的"goto"都有普遍的偏见;gotos 被认为是不优雅的,使您的代码难以遵循。可以肯定的是,这种偏见背后有一些事实,尽管 C# 经过精心设计,因此"goto"的最严重滥用是不可能的或不太可能。 (C# 仅允许同一块内的 gotos 或从内部块到其包含块之一的 goto。它从不允许 goto 从外部块进入内部块,或者在没有嵌套关系的两个块之间。这大大降低了"意大利面条代码"的可能性。

我假设既然你正在上一门课程,你才刚刚开始学习 C#。随着您的进步,您将了解比打开案例更优雅的控制流技术。

当我们批评您的代码时:请考虑使用 int.TryParse 而不是 Convert.ToInt32 ,并确保处理用户键入非整数内容的情况。

看这篇文章

基本上,开关不能在 case 语句中具有计算语句。必须对它们进行静态评估。

怎么样:

int travel2A = Convert.ToInt32(travel2);
if( travel2A < 1 || travel2A > 10 )
    travel2A = 2;
switch( travel2A ) { ... }
编译器

错误A constant value is expected说明了一切。

调试模式下运行它时,这在 C# 中是不可能的(VB Select操作略有不同(的原因得到了很好的证明。 每当您遇到 switch 语句时,您都会注意到代码将跳转到所选大小写。 虽然您可以通过跳过几次比较来显着提高性能,但它限制了灵活性。

我过去解决这个问题的一种方法是使用匿名方法递归。 因此,您将使用将重新调用switch语句的方法调用,而不是使用 goto case(travel2a)

Action<int> foo = null;
foo = (i) =>
{
    switch (i)
    {
        case 1:
            Console.WriteLine("1");
            break;
        case 2:
            Console.WriteLine("1");
            break;
        case 3:
            Console.WriteLine("1");
            break;
        default:
            //goto case (i%3);
            foo(i % 3);
            break;
    }
};
foo(4);

您可以将case代码组织为一种方法,并简单地调用它:

switch (location)
{
    case 1:
        gocave();
        break;
    case 2:
        gocave();
        break;
    case 3:
        donotgocave();
        break;
}

或者将复杂的逻辑拆分为原语:

bool gocave = false;
bool eatmushroom = false;
switch (location)
{
    case 1:
        gocave = true;
        break;
    case 2:
        gocave = true;
        eathmushroom = true;
        break;
    case 3:
        break;
}
if(gocave) {...}
if(eatmushroom) {...}