C# 可以用goto';s
我知道goto是一种糟糕的设计实践。但想象一下,我们被困在一个荒岛上,工具箱里除了gotos和ifs什么都没有。那么这不是:C# 可以用goto';s,c#,goto,C#,Goto,我知道goto是一种糟糕的设计实践。但想象一下,我们被困在一个荒岛上,工具箱里除了gotos和ifs什么都没有。那么这不是: int i = 0; while (i < 10) i++; inti=0; 而(i
int i = 0;
while (i < 10) i++;
inti=0;
而(i<10)i++;
与此相同:
int i = 0;
loop: if (i < 10) { i++; goto loop; }
inti=0;
循环:如果(i<10){i++;转到循环;}
?
在c语言中,仅仅使用条件逻辑、赋值/更改变量、方法调用和跳转,你就可以做任何你通常能做的事情,这难道不是真的吗?是的,你可以重新编写任何程序,使其具有相同的输出,而不必使用任何循环。方法调用都可以内联,所以技术上也不需要这些调用。当然,类和接口对于任何逻辑都不是必不可少的。事实上,你可以用if,goto,赋值和加法来做任何事情。也许你甚至不需要那么多。是的,这是可能的。最终,这就是组装的工作方式。在汇编中没有循环这样的东西。要更改代码中的位置,必须使用等价的“goto”(通常是
jmp
或某种形式的“branch”)或函数调用(如果存在)
然而,如果我继承的代码库使用了
goto
s,我要么从头重写它,要么在不允许的情况下退出。从技术上讲?是的,绝对是。Goto程序是图灵完备的,因此你可以用它们来表示一切。最后,机器代码非常类似于goto程序,因为循环和其他操作都是使用条件跳转完成的。当然,在.NET中,您不能只使用goto。在某个时候,您会遇到这样的情况:要么使用其他不是这样编写的代码,要么语言结构迫使您执行其他操作(生成类、方法、函数等)。但从技术上讲,是的
你应该怎么做?绝对不是。Goto程序很难维护,当C#编译成中间语言时,中间语言使用跳转,但级别更高,这样做可能会损失大量性能。此外,虚拟机可以在“普通”代码中进行大量优化,而当您将虚拟机放在固定的goto模式中时,它无法进行优化
顺便说一句,您的原始代码编译成这个IL,这基本上是您使用goto(我的注释)编写的:
//i=0
IL_0001:ldc.i4.0//将整数值0加载到堆栈
IL_0002:stloc.0//i//将堆栈值存储在局部变量0中
//转到循环条件
IL_0003:br.s IL_0009//跳转到IL_0009
//循环开始:
//i=i+1
IL_0005:ldloc.0//i//将变量0加载到堆栈
IL_0006:ldc.i4.1//将整数'1'加载到堆栈
IL_0007:添加//添加最上面的两个堆栈值
IL_0008:stloc.0//i//将结果存储在局部变量0中
//循环条件:
//如果(i<10){goto循环开始}
IL_0009:ldloc.0//i//将变量0加载到堆栈
IL_000A:ldc.i4.s 0A//将整数'10'加载到堆栈
IL_000C:clt//比较最上面的两个堆栈值
IL_000E:stloc.1//CS$4$0000//将堆栈值存储在局部变量1中
IL_000F:ldloc.1//CS$4$0000//将变量1加载到堆栈
IL_0010:brtrue.s IL_0005//如果堆栈值为true,则跳转到IL_0005
转到并不一定有什么本质上的不好。是什么原因使其不应被使用,如下所示:
- 它极易被滥用,并且在正确使用时需要极大的控制;即使这样,它也会使代码更难阅读
- 始终可以使用更具可读性的结构,如
while
、do
、for
或foreach
因为同时使用其他东西总是可能的,而且总是更好,所以永远不应该实际使用goto
我听说的一个可能的例外是打破了深嵌套:
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++)
for (int z = 0; z < 100; z++)
if (condition)
goto end;
end: ;
for(int x=0;x<100;x++)
对于(int y=0;y<100;y++)
对于(intz=0;z<100;z++)
如果(条件)
转到终点;
完:;
VS
for(int x=0;x<100,!条件;x++)
对于(int y=0;y<100,!条件;y++)
对于(intz=0;z<100,!条件;z++)
为了更直接地回答您的问题,是的,完全可以使用goto
s而不是while
s、do
s等执行所有控制流。。。我甚至可能会建议,这对实践来说是一个很好的挑战,但在任何真正的代码中都不是,而且尝试在汇编中编码可能是一种更好的学习体验,而不是强迫自己使用goto
s.不。如果编程是这样的话,我宁愿辞职,做一个无家可归的人beggar@HighCore这是可能的。这就是组装的工作原理。它实用吗?“没有。”科尔约翰逊说得对。我的观点仍然站得住脚,尽管他们是平等的。但它也等于:inti=10代码>。如果您将自己限制为使用gotos模拟标准控制结构(而不是像意大利面条一样跳来跳去),那么代码的维护并不比使用正确的控制结构的代码困难。
for (int x = 0; x < 100; x++)
for (int y = 0; y < 100; y++)
for (int z = 0; z < 100; z++)
if (condition)
goto end;
end: ;
for (int x = 0; x < 100, !condition; x++)
for (int y = 0; y < 100, !condition; y++)
for (int z = 0; z < 100, !condition; z++)