好的 - 所以也许我累了,但我正在尝试找到一种方法来做以下事情(一个似乎......更优雅?)
loopTwice
)loopTwice
由循环内容使用(并修改其行为)以执行互斥功能loopTwice
为真,我希望循环执行两次,首先使用值true,然后使用值false loopTwice
为false,我希望循环只执行一次,值为false loopTwice
,因此最终值...这似乎有足够的意义,但出于某种原因,我的大脑没有提出任何比一个有一个if条件的while循环更优雅的东西休息:
// loopTwice is already set as true or false
while (true) //this seems ugly, not to mention breakable...
{
DoThis(loopTwice); //these act slightly differently based upon loopTwice
DoThat(loopTwice); //these act slightly differently based upon loopTwice
DoAnotherThing(loopTwice); //these act slightly differently based upon loopTwice
if (!loopTwice) break;
loopTwice = false;
}
这段代码(好吧,不是这段代码,而是等效的代码......)完全按照我的意愿工作而没有配置另一个变量(我猜这不是一件坏事,但我没有看到使用另一个变量制作任何比这更优雅的循环......)
在我看来,必须有一些我缺少的东西(一种方法可以循环两次,如果某些东西是真的,一次如果某些东西是假的,“假”值总是最后的 - 并且最好没有第二个变量,比如一个计数器或第二个标志,表示循环已经运行一次。)
使用计数器或旗帜实际上更优雅吗? (我想在过去几十年的计算机中,它并没有真正冒险破坏内存要求或任何东西,是吗......)。将此分解为函数并使用递归会更优雅吗?嗯...
当然,优雅是在旁观者的眼中......
答案 0 :(得分:3)
我假设你已经为两个循环迭代提供了足够的公共代码,因此将它作为循环保留是有意义的。您可以轻松地将其写为do
... while
循环:
do {
....
} while (!(loopTwice = !loopTwice));
答案 1 :(得分:3)
这里只是添加另一种方法,递归!
void MyRecursiveMethod(bool repeat)
{
// Do something here.
// Should we do this more than once?
if(repeat)
MyRecursiveMethod(false); // Don't do this indefinitely!
}
编辑:如果需要,这也允许您轻松地将其扩展到 n 次迭代,而不仅仅是两次。
例如,将来您决定可能需要执行此操作三次,您可以将其更改为int repeatCount
而不是简单的bool
,然后再减少每一次。
答案 2 :(得分:2)
使用布尔标志来表示你想循环多少次似乎模糊了你对读者的意图(至少,这个)。我更喜欢这样的东西:
int loops = someFlag ? 2 : 1;
while(loops-- > 0) {
DoThis(someFlag);
DoThat(someFlag);
DoAnotherThing(someFlag);
}
它清楚地表达了你的意图:如果标志为真,则循环2次,如果标志为假则只执行一次。此外,它可以让你很容易在未来修改循环迭代。没有递归,没有附加功能,能够适应所需的迭代次数,可读性等。
修改强>
添加内部标志以表示在最后一次迭代中始终具有false
标志的意图,这仍然适应所需的循环次数。另外,我改为预先递减循环变量,因此内部循环不与0
进行比较:
int loops = someFlag ? 2 : 1;
while (--loops >= 0) {
bool lastIter = loops == 0;
DoThis(someFlag && !lastIter);
...
}
答案 3 :(得分:1)
这种感觉就像一个'倒计时'循环,但有布尔。你可以弄清楚要使用的布尔值:
var iterations = new[] {true,false}.SkipUntil(e => e == loopTwice);
// or
var iterations = new[] {true,false}.Skip(loopTwice ? 0 : 1);
// or
var iterations = loopTwice? new[] {true, false} : new[] {false};
然后使用它们:
foreach (var b in iterations) {
DoThis(b);
DoThat(b);
DoAnotherThing(b);
}
答案 4 :(得分:0)
这样的事情会起作用还是让你感兴趣?
switch (count) {
case 0:
break;
case 1:
doThisThingSecond();
goto case: 2;
case 2:
doThisThingFirst();
break;
}
答案 5 :(得分:0)
重新考虑要求之后,我真的建议添加另一种方法。包装另一种方法或一堆方法是一种非常常见的模式(外观等),并且会使您的代码具有可读性。使用Linq和递归的所有这些混淆都会破坏您的原始意图。除非您在20世纪80年代的硬件上运行,否则添加其他方法或变量对代码性能的影响可以忽略不计。
这是我的另一个建议:
void ExecuteWithFlag(bool withFlag)
{
DoSomething(withFlag);
DoSomethingElse(withFlag);
// etc.
}
void Execute()
{
ExecuteWithFlag(true);
ExecuteWithFlag(false);
}