C# 跳转到代码C中的某一行#
我有几个方法是从其他几个方法中调用的。当在某些方法中执行某个操作时,我想回到第一个方法并跳过其余的代码。目前,我使用C# 跳转到代码C中的某一行#,c#,goto,C#,Goto,我有几个方法是从其他几个方法中调用的。当在某些方法中执行某个操作时,我想回到第一个方法并跳过其余的代码。目前,我使用booleans检查程序的“状态”,但我希望避免这样做,因为这些方法应该是void,因为本质上它们不需要返回任何东西。我发现了类似于goto的东西,但这只适用于相同的方法 问题:在C#中有没有其他方法可以跳转到代码中的特定点?我在其他语言上找到了一些东西,但在C语言上找不到很多 当前情况: void test1() { bool status = t
booleans
检查程序的“状态”,但我希望避免这样做,因为这些方法应该是void
,因为本质上它们不需要返回任何东西。我发现了类似于goto
的东西,但这只适用于相同的方法
问题:在C#中有没有其他方法可以跳转到代码中的特定点?我在其他语言上找到了一些东西,但在C语言上找不到很多
当前情况:
void test1()
{
bool status = test2();
if (!status)
return; // the other stuff will not get done
Debug.WriteLine("Initialization OK");
}
bool test2()
{
bool status = test3();
if (!status)
return false; // the other stuff will not get done
// do other stuff
return true;
}
bool test3()
{
if (xxx)
return false; // the other stuff will not get done
else
// do other stuff
return true;
}
void test1()
{
test2();
// do other stuff
Debug.WriteLine("Initialization OK");
GOTOHERE:
Debug.WriteLine("Initialization NOT OK");
}
void test2()
{
test3();
// do other stuff
}
void test3()
{
if (xxx)
**GOTOHERE**; // Go directly to the location in test1() so that all unnecessary code is skipped
// do other stuff
}
通缉情况:
void test1()
{
bool status = test2();
if (!status)
return; // the other stuff will not get done
Debug.WriteLine("Initialization OK");
}
bool test2()
{
bool status = test3();
if (!status)
return false; // the other stuff will not get done
// do other stuff
return true;
}
bool test3()
{
if (xxx)
return false; // the other stuff will not get done
else
// do other stuff
return true;
}
void test1()
{
test2();
// do other stuff
Debug.WriteLine("Initialization OK");
GOTOHERE:
Debug.WriteLine("Initialization NOT OK");
}
void test2()
{
test3();
// do other stuff
}
void test3()
{
if (xxx)
**GOTOHERE**; // Go directly to the location in test1() so that all unnecessary code is skipped
// do other stuff
}
从您的方法返回一些指示您以后应该做什么的内容正是您应该做的。因此,返回一个布尔值,指示
test2
或test3
是否成功,并使用该值指示是否要继续。现在不要使用goto,因为它只是利兹到意大利面的代码,很难维护。要确定在什么情况下控制流应该跳转到GOTOHERE
,您需要扫描整个代码以查找特定的goto
-语句
在您的情况下,您希望指示某些初始化代码是否正常工作。因此,您还可以引发异常:
void test3()
{
if (xxx)
throw new Exception("Some text");
// do other stuff
}
这样,您不需要从方法中返回任何内容,但可以适当地处理异常:
void test1()
{
try { test2(); }
catch {
// some exception-handling such as logging
return;
}
Debug.WriteLine("Initialization OK");
}
这样做的好处是,如果
test3
成功,您不需要签入test2
,允许您让异常冒泡通过您的方法,直到它最终被catch
处理。如果在整个调用堆栈中找不到catch
,您的应用程序可能会终止。我不建议这样做,但您的问题的简单答案是使用goto
语句
见:
然而,您实际上应该从以前的方法调用返回值,您可以使用这些值来确定是否需要运行其他代码
您也可以抛出
异常,但一般来说,我不喜欢使用它们来控制流,除非情况异常(我想这就是它的名字)。如果您希望控件以这种或那种方式流动,那么它也不例外。C#确实有goto
关键字,它的工作方式与其他语言一样。将标签声明为label\u you\u want\u jump\u to:
,并使用goto label\u you\u want\u jump\u to
()
既然如此,使用goto通常是个坏主意,尤其是以这种方式。通过稍微重构,您的问题可能会更容易解决。将
test3
拆分为两个函数,减少嵌套量可能就是这样一种方法。您还可以在test3
中抛出异常,并在test1
中捕获它。这完全取决于你想做什么。我惊讶地发现C#确实支持GOTO命令。但它的设计允许从深层嵌套循环中退出
本文对此进行了解释,并给出了许多示例:
但是
除非您还在1970年编写代码,否则使用GOTO被认为是非常糟糕的做法。这使得代码维护非常困难。它甚至会导致问题和性能问题,使JIT编译器的工作更加困难
现在的go-to语句太原始了,太多了
把节目搞得一团糟的邀请
埃德斯格·W·迪克斯特拉
如果你去掉了显式布尔(这是多余的),在我看来,你的(相当做作的)例子看起来更“干净”:
void test1()
{
if (test2())
{
Debug.WriteLine("Initialization OK");
}
}
bool test2()
{
return test3();
}
bool test3()
{
return xxx;
}
我也更喜欢使用肯定条件而不是否定条件,因此“if(true)”而不是“if(!false)”。这避免了双重否定,这是很难理解的
我们正在有效地使用。我们可以使用普通逻辑运算符组合谓词(返回bool的方法除外,没有副作用)。考虑这个例子:
bool test4()
{
if (test1())
{
if (test2())
{
return true;
}
else
{
return false;
}
}
else
{
return false;
}
}
我们注意到,这只是test1和test2的逻辑连接(and),因此可以简单地使用&&conjunction操作符使其更清晰:
bool test4()
{
return test1() && test2();
}
对于逻辑析取(or)也类似:
我们可以这样写:
bool test5()
{
return test1() || test2();
}
我确实理解你的观点,但是打破项目顺序(又称跳跃)不是一个好的做法。您的代码变得不可读,因为读者需要从一个地方跳到另一个地方。无法跳出当前方法的原因如下: 下面是一个真正简化的解释。我对许多细节感到幸灾乐祸。
如果您了解这些,您就会知道运行时将为每个新方法调用在堆栈上推送一个新的堆栈框架。新的堆栈框架包含方法的局部变量以及其他实现细节。如果您想跳转到另一个方法,运行时需要在堆栈上推送一个新的堆栈框架,以便为该方法创建这些局部变量。因此,goto将成为方法调用,而不是跳转语句。这很奇怪,不是你/我们想要的。在这样的场景中使用普通的方法调用,而不是跳转语句
有广泛接受的跳跃语句,如:代码>返回<代码>,<代码>破解< /代码>和<代码>继续<代码>。
<代码> GOTO 不是其中之一,虽然我认为<代码> Goto case < /C>是某些情况下的有效解决方案。
返回有关下一步操作的信息是正确的行为。
我确实同意,从语义的角度来看,返回bool不是很有表现力,至少与您当前的方法名称不同。命名改进建议:
void DoTest1();
bool TryTest2();
bool TryTest3();
供参考
从您的方法返回一些指示您以后应该做什么的内容正是您应该做的。因此,返回一个布尔值,指示是否
test2<