3

假设你想循环 3 个这样的元素:

for(int i=0; i<3; i++)
{
    doSomething();
}

当然,这与说:doSomething(); doSomething(); doSomething();.

现在,假设您想在每次迭代之间做一些事情,就好像您正在编写这样的代码: doSomething(); doBetween(); doSomething(); doBetween(); doSomething();

注意如何doSomething()被调用 3 次,但doBetween()被调用了 2 次。

现在,我知道如何在循环中执行此操作的唯一方法是:

for(int i=0; i<3; i++)
{
    doSomething();
    if(i<2)
        doBetween();
}

对我来说,在循环中运行该条件似乎效率低下。它还使您必须查看两次才能理解编程意图。另外,如果您将“3”更改为“for”标题中的其他内容,您可能很容易忘记更改条件,尤其是随着逻辑的增长。不仅如此,这个技巧在 foreach 循环中也不起作用,因为没有简单的方法来检测我们是否正在运行最后一次迭代。

您有什么技巧可以让您以更好的性能、更好的可读性、更好的可维护性或在 foreach 循环中执行此类操作?

4

7 回答 7

3
for(int i = 0; i < 3; i++) {
    if(i > 0) {
        doBetween();
    }
    doSomething();
}
于 2012-09-09T22:11:58.433 回答
3

简单的东西呢?

for(int i = 0; i < 3; i++) {
    doSomething();
    doBetween();
}
doSomething();
于 2012-09-09T22:15:56.140 回答
1

假设您想在 foreach 中迭代的任何内容上“doSomething”和“doBetween”:

bool firstComplete = false;

foreach(Item i in ItemList)
{
   if (firstComplete)
   {
      doBewteen(i);
   }
   else
   {
      firstComplete = true;
   }

   doSomething(i);
}
于 2012-09-09T22:17:11.537 回答
1

您总是可以编写一个可重用的函数,除非您需要大量重用它,否则不确定这是一个好主意

    public static IEnumerable<TSource> ForEach<TSource>(this System.Collections.Generic.IEnumerable<TSource> source, Action<TSource> action, Action<TSource> between)
    {
        bool first = true;
        foreach (TSource item in source)
        {
            if (first) first = false; else between();
            action(item);
        }
        return source;
    }

这将被称为:

myList.ForEach(i => DoSomething(), i => DoBetween());

或者

Enumerable.Range(0, 3).ForEach(i => DoSomething(), i => DoBetween());
于 2012-09-09T22:23:49.717 回答
1
{
    int i=0;

    if(i<3){
        while(true){
            doSomething();
            i++;
            if(i<3){
                doBetween();
            }
            else{
                break;
            }

        }
    }
}

诚然,它看起来最晦涩难懂,但两个语句只写一次,每次迭代只有一次比较。如果最初不满足条件,则不会发生任何事情,并且它也不使用任何辅助变量。你只需要写两次条件。

于 2019-08-27T18:35:42.940 回答
0

没有任何内置的东西。你可以做你自己的自定义枚举器,它会在两者之间调用一些东西,但是调用它会同样复杂。

无论您如何解决它,您都无法绕过对每次迭代进行检查。像这样的简单检查几乎不会损害性能。

我通常为此使用布尔标志:

bool first = true;
for (int i = 0; i < 3; i++) {
  if (first) {
    first = false;
  } else {
    doBetween();
  }
  doSomething();
}

您还可以考虑将一个迭代移出循环:

doSomething();
for (int i = 1; i < 3; i++) {
  doBetween();
  doSomething();
}

但是,如果循环可能是空的(零项),您必须先检查它。

于 2012-09-09T22:17:31.490 回答
0

这将允许您在进入循环之前定义起点和终点......

int start = 0;
int limit = 3;
for (int i == start; i < limit; i++) {
    doSomething();
    if (i > start && i < limit - 1) {
        doBetween();
    }
}
于 2012-09-10T00:52:55.133 回答