我在具有以下结构的C#方法中有一个循环。
do
{
getUserInput();
if (inputIsBad)
{
doSomethingElse();
}
} while (inputIsBad);
或者,有一个while循环:
getUserInput();
while (inputIsBad)
{
doSomethingElse();
getUserInput();
}
但是两种方法都使用冗余代码:do-while同时具有if语句和while循环来检查相同条件; while循环在循环之前和循环内部都调用getUserInput()。
是否有一种简单的,非冗余的,非ad hoc的方法来完成这些方法模式的工作,无论是一般还是在C#中,只需要编写一次每个基本组件?
假定getUserInput(..)
可以转换为产生布尔值的表达式* ..
while (getUserInput()
&& isBadInput()) {
doSomethingElse();
}
// Prompts for user input, returns false on a user-abort (^C)
private bool getUserInput() { .. }
注释中显示的其他变体(假定没有非本地状态)。>>
*通常,它总是可以作为包装函数编写-参见C#7中引入的Local Functions。 (还有其他方法可以达到相同的效果,我认为其中有些“太聪明”。)
// local function bool getUserInputAlwaysTrue() { getUserInput(); // assume void return return true; } while (getUserInputAlwaysTrue() && isBadInput()) { doSomethingElse(); }
在某些情况下,可以遵循此步骤进一步推广逻辑。一般前提是:
getUserInput()
总是在下一个isBadInput()
之前调用。
// local function or member method
// Prompt for user input, returning true on bad input.
bool getCheckedUserInput() {
getUserInput(); // assume void return
return isBadInput();
}
while (getCheckedUserInput()) {
doSomethingElse();
}
do
{
getUserInput();
if (!inputIsBad) break;
doSomethingElse();
} while (true);
我将使用一个布尔变量,您需要在循环主体之外声明该变量。这样,您只需运行一次inputIsBad
检查。我也将其转换为一种方法,因为这似乎更合逻辑。
基于user2864740's的答案: