如何避免在C#while和do-while循环中进行代码重复?

问题描述 投票:4回答:4

我在具有以下结构的C#方法中有一个循环。

do
{
     getUserInput();
     if (inputIsBad)
     {
          doSomethingElse();
     } 
} while (inputIsBad);

或者,有一个while循环:

getUserInput();
while (inputIsBad)
{
     doSomethingElse();
     getUserInput();
}

但是两种方法都使用冗余代码:do-while同时具有if语句和while循环来检查相同条件; while循环在循环之前和循环内部都调用getUserInput()。

是否有一种简单的,非冗余的,非ad hoc的方法来完成这些方法模式的工作,无论是一般还是在C#中,只需要编写一次每个基本组件?

c# loops while-loop language-agnostic do-while
4个回答
1
投票

假定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();
}

1
投票
do
{
     getUserInput();

     if (!inputIsBad) break;

     doSomethingElse();

} while (true);

0
投票

我将使用一个布尔变量,您需要在循环主体之外声明该变量。这样,您只需运行一次inputIsBad检查。我也将其转换为一种方法,因为这似乎更合逻辑。


0
投票

基于user2864740's的答案:

© www.soinside.com 2019 - 2024. All rights reserved.