4

我定义了以下扩展方法:

public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
   foreach (T obj in sequence)
   { 
      action(obj); 
   } 
}

然后我可以将其用作:

new [] {1, 2, 3} // an IEnumerable<T>
.ForEach(n => 
{
  // do something 
});

我希望能够利用continuebreak在我的扩展方法内部,这样我就可以做到:

new [] {1, 2, 3}
.ForEach(n => 
{
    // this is an overly simplified example
    // the n==1 can be any conditional statement
    // I know in this case I could have just used .Where
    if(n == 1) { continue; }
    if(n == -1) { break; }      
    // do something 
});

这些关键字只能在for、或循环foreach中使用吗?whiledo-while

4

3 回答 3

7

这些关键字只能在 for、foreach、while 循环中使用吗?

是的。这些语句仅限于循环类型。正如文档所说

continue 语句将控制权传递给包含它的while、do、for 或 foreach语句的下一次迭代。

并且

break 语句终止它出现的最近的封闭循环或 switch 语句。控制权被传递给终止语句之后的语句(如果有)。

我建议你使用一个常规的foreach,它是自我表达的。我认为任何在扩展方法中使用语义的尝试ForEach都会导致比使用常规循环更奇怪的代码。

我的意思是,这不是更简单吗?:

var arr = new [] {1, 2, 3}
foreach (int number in arr)
{
    if(n == 1) { continue; }      
    if(n == -1) { break; }      
}
于 2015-07-16T13:02:55.990 回答
3

除了 Yuval 的回答,我想补充一点,您可以按如下方式实现类似的内容:

将 更改Action<T>为 a Func<T, bool>,它接受一个T参数并返回一个bool结果。

“继续”的情况可以通过根据条件从函数返回来轻松处理,从而继续循环的下一次迭代。

“break”的情况可以通过bool从函数中返回一个指示是否继续的来处理:

public static void ForEach<T>(this IEnumerable<T> sequence, Func<T, bool> action)
{
  foreach (T obj in sequence)
  { 
    if (!action(obj)) 
      break;
  }
}

new [] {1, 2, 3}.ForEach(n => 
{
    if(n == 1) { return true;}      
    if(n == -1) { return false; }  

    // do something 
    ...
    return true;
});
于 2015-07-16T13:06:44.400 回答
1

是的,这些关键字仅限于whiledoforforeach(正如 Yuval 所引用的)。

此代码与您询问的大致相同:

bool shouldBreak = false;

new [] {1, 2, 3}
.ForEach(n => 
{
    if (!shouldBreak)
    {
        if(n == 1) { /* no action */ }      
        else if(n == -1) { shouldBreak = true; }
        else
        {
            // do something 
        }
    }
});
于 2015-07-16T13:05:44.597 回答