是否可以用 goto 做所有事情?

Coo*_*Bro 2 c# goto

我知道 goto 是一种糟糕的设计实践。但想象一下,我们被困在一座荒岛上,工具箱里除了 goto 和 if 之外什么都没有。那岂不是这样:

    int i = 0;
    while (i < 10) i++; 
Run Code Online (Sandbox Code Playgroud)

与此相同:

    int i = 0;
    loop: if (i < 10) { i++; goto loop; }
Run Code Online (Sandbox Code Playgroud)

难道你真的可以使用条件逻辑、分配/更改变量、方法调用和跳转来完成在 C# 中通常可以做的任何事情吗?

pok*_*oke 5

从技术上讲?是的,一点没错。Goto 程序是图灵完备的,因此你可以用它们来表示一切。最后,机器代码与 goto 程序非常相似,因为循环和其他内容都是使用条件跳转完成的。当然,在 .NET 中,\xe2\x80\x99 不能使用goto。在某些时候,您会遇到这样的情况:您要么使用其他不是这样编写的代码,要么您处于语言结构迫使您做其他事情的位置(创建类、方法、函数等) .)。但从技术上来说,是的。

\n\n

然而你应该这样做吗?绝对不。Goto 程序非常难以维护,并且当 C# 编译成中间语言时,它使用跳转,但在更高级别上,这样做时您可能会损失大量性能。此外,虚拟机可以在 \xe2\x80\x9cnormal\xe2\x80\x9d 代码中进行大量优化,当您将其放入固定的 goto-schema 时,它可以\xe2\x80\x99t 进行优化。

\n\n

顺便提一句。你的原始代码编译成这个 IL,这本质上是你使用 goto 编写的(我的注释):

\n\n
// i = 0\nIL_0001: ldc.i4.0                  // Load integer value 0 to stack\nIL_0002: stloc.0   // i            // Store stack value in local variable 0\n\n// goto loop-condition\nIL_0003: br.s      IL_0009         // Jump to IL_0009\n\n// loop-start:\n// i = i + 1\nIL_0005: ldloc.0   // i            // Load variable 0 to stack\nIL_0006: ldc.i4.1                  // Load integer `1` to stack\nIL_0007: add                       // Add top two stack values\nIL_0008: stloc.0   // i            // Store result in local variable 0\n\n// loop-condition:\n// if (i < 10) { goto loop-start }\nIL_0009: ldloc.0   // i            // Load variable 0 to stack\nIL_000A: ldc.i4.s  0A              // Load integer `10` to stack\nIL_000C: clt                       // Compare top two stack values\nIL_000E: stloc.1   // CS$4$0000    // Store stack value in local variable 1\nIL_000F: ldloc.1   // CS$4$0000    // Load variable 1 to stack\nIL_0010: brtrue.s  IL_0005         // Jump to IL_0005 if stack value is true\n
Run Code Online (Sandbox Code Playgroud)\n