Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/288.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
使用goto案例(变量);在C#开关中_C#_Switch Statement_Goto - Fatal编程技术网

使用goto案例(变量);在C#开关中

使用goto案例(变量);在C#开关中,c#,switch-statement,goto,C#,Switch Statement,Goto,我正在Visual Studio C#console中为一门课程编写一篇文本冒险,并决定使用switch语句而不是if-else链,因为goto case非常有用(到目前为止它已经非常有效)。我知道开关本身中的每种情况都必须是常数,但我想知道这是否也扩展到使用goto情况。例如,我有: switch (location) { case 1: break; case 2: break; case 3: break; //I have 10 cases, each representin

我正在Visual Studio C#console中为一门课程编写一篇文本冒险,并决定使用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
}
string travel2=Console.ReadLine()//输入一个表示每个位置的整数
int travel2A=转换为32(travel2);
如果(1见此


基本上,开关不能在case语句中有求值语句。它们必须进行静态求值。

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

我要提醒你,任何严重依赖任何形式的“goto”的解决方案都是不可取的。对任何形式的“goto”都存在普遍的偏见;goto被认为是不雅观的,并且使你的代码难以遵循。尽管C#经过精心设计,使得最恶劣的“goto”滥用行为成为可能,但这种偏见背后确实存在一些事实不可能或不太可能。(C#只允许在同一块内或从内部块转到其包含的块之一。它从不允许从外部块转到内部块,或在没有嵌套关系的两个块之间。这大大降低了“意大利面代码”的可能性。)

我想,既然你正在学习一门课程,你就刚刚开始学习C#。随着你的进步,你将学习到比打开案例更优雅的控制流技术

当我们批评您的代码时:考虑使用<代码> In .TyPARSE < /C> >而不是<代码> Real.ToTut32 ,并确保您处理用户键入不是整数的情况。

如何:

int travel2A = Convert.ToInt32(travel2);
if( travel2A < 1 || travel2A > 10 )
    travel2A = 2;

switch( travel2A ) { ... }
inttravel2a=Convert.ToInt32(travel2);
如果(travel2A<1 | | travel2A>10)
travel2A=2;
开关(travel2A){…}

编译器错误
需要一个常量值
说明了一切

这在C#中不可能实现的原因(VB
Select
操作略有不同)当您在调试模式下运行它时,它会得到很好的演示。每当您遇到
switch
语句时,您都会注意到代码将跳转到所选的情况。虽然您通过跳过几个比较来获得显著的性能提升,但它限制了灵活性

过去我解决这个问题的一种方法是使用非规则方法进行递归。因此,不要使用
goto case(travel2a)
,而是使用一个方法调用来重新调用
switch
语句

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);
操作foo=null;
foo=(i)=>
{
开关(一)
{
案例1:
控制台。写入线(“1”);
打破
案例2:
控制台。写入线(“1”);
打破
案例3:
控制台。写入线(“1”);
打破
违约:
//后藤病例(i%3);
foo(i%3);
打破
}
};
foo(4);

您可以将
案例
代码组织为一种方法,并简单地称之为:

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) {...}

如果您在
开关
内,则只能
转到
案例
,而您不在第二个示例中。您没有标签“2”已定义。请参阅,然后立即查看并停止使用
goto
。仅仅因为不能使用
goto
,并不意味着不能使用
switch
语句来实现此设计。请参阅我的答案以了解解决方法。您提到了对C的陌生。我建议,一旦您的代码正常工作,您可以尝试将其发布到以进行构造有意思的批评。谢谢!这只是我在C#的第二周,所以我还在熟悉它。我将切换到if else for traveling。谢谢你的int.TryParse推荐。我会马上做。@RussellDahlke:不客气。听起来你在思考控制流方面做得不错。现在退一步问问你自己如果你能更抽象地概念化你的流程。文本冒险游戏基本上是一个状态机。状态机有以下流程:(1)创建开始状态,(2)获取输入,(3)计算出当前状态和输入对状态的更改,(4)如果新状态是停止状态,则结束程序,(5)转到2。如果你能像这样组织你的程序,它可能更容易理解。显然(3)是困难的部分!