解决过度使用break语句的方法
本文关键字:语句 方法 break 解决 | 更新日期: 2023-09-27 17:51:21
我有一个功能完备的程序,现在我正在重构它。我只是在学习c#的过程中,所以最初的代码是相当可怕的,尽管它运行得很好。该程序的要求之一是用户能够在任何时候返回到主菜单。我是这样做的:
static bool bouncer = false
static void Exit(string input)
{
if (input == "'t")
{
bouncer = true
}
}
static string Prompt(string msg)
{
// takes input and passes it to Exit() then returns the input
}
static string FunctionA()
{
while(true)
{
if (bouncer == true)
{
break;
}
Prompt("whatever")
if (bouncer == true)
{
break;
}
Prompt("whatever")
if (bouncer == true)
{
break;
}
// return some stuff
}
}
static void Main()
{
bouncer = false
// writes the menu to console and handles UI
// FunctionA
{
如果用户在任意输入点输入"tab"字符,则变量bouncer被设置为true。break语句条件的激增提供了实际返回到Main()的结构。这显然不是一个很好的解决方案,它使代码难以阅读。
我认为完成相同任务的其他尝试有:
直接跳转回Main()的Goto语句。我放弃了这个,因为goto在c#中的作用范围非常有限,我认为没有任何好的方法可以使它在这种情况下工作。
直接从Exit()调用Main()。这可能是一个坏主意,我不能这样做,因为显然Main()在某种程度上是"受保护的"。
使用事件对按下TAB或ESC做出反应。我不清楚如何使用事件来做到这一点,因为我仍然无法从事件中跳出来。我的理解是,break语句实际上必须包含在需要中断的循环中,而不是写入从循环内调用的不同函数中。
任何建议都非常感谢。我希望有一些事情要做的事件处理,或者我忽略了一些更简单的东西。谢谢!
作为编码风格的问题,它的工作方式,但被认为是丑陋的。不幸的是,如果你需要在工作之间立即休息一下,没有很多方法可以解决这个问题。
你可以改变你当前使用break的格式为使用"if( bContinue ) { /* do next section of work */ }
"控件样式。它将跳出while循环的代码更改为:
static string FunctionA()
{
bool bContinue = true;
while( true == bContinue )
{
// Do initital work.
//
// Initial work can set bContinue to false if any error condition
// occurs.
if( true == bContinue )
{
// Do more work.
int returnCheck = MakeACall(); // Presume MakeACall returns negative interger values for error, 0 or positive values for success or success with condition/extra information.
if( 0 < returnCheck )
{
bContinue = false;
}
}
if( true == bContinue )
{
Prompt("whatever")
// Do more work.
bContinue = MakeASecondCall(); // Presume that MakeASecondCall returns true for success, false for error/failure
}
if( true == bContinue )
{
Prompt("whatever")
// Do more work.
// If error encountered, set bContinue to false.
}
if( true == bContinue )
{
Prompt("whatever else")
// Do more work.
// If error encountered, set bContinue to false.
}
// Done with loop, so drop out.
bContinue = false;
// return some stuff
}
}
看看你的伪代码,它读起来就像你只在你的工作循环中做了一次传递。如果是这样,您可以切换到Do-While(false)
格式,并使用中断只是下降到底部。或者,如果你只做一次通过你的FunctionA
,只要去掉While
或Do-While
控制结构,只使用if(true==bContinue){ /* Do more work */ }
。它不是最干净的代码,但是当您执行长时间的串行工作时,如果您不打算使用while
或do-while
来控制流,您最终会得到这样的结构。
使用if(bContinue){}
风格的缺点是,当错误条件发生在过程的早期阶段时,如果错误发生在工作的顶部附近,那么代码不会像break
一样快速地从while()
或do-while()
结构中退出,因为代码将测试一系列if
语句,然后跳过它们。但它是可读的,如果你使用一个描述性的名称为你的控制变量(即,nContinue
或bContinue
或workLoopControl
),它应该是相当明显的,它是主控制标志的功能的工作流程,无论谁工作或审查你之后的代码。
不要使用无限循环和break语句,而是尝试使用条件标志。
static void FunctionA()
{
bool done = false;
string response = string.Empty;
while (!done)
{
response = Prompt("whatever");
if(response == ''t')
{
done = true;
}
}
}
作为旁注,我不知道为什么你有'string'作为几个方法的返回类型(例如,'FunctionA'),当你不使用返回值。这就是为什么我上面给出的代码是'void'