【问题标题】:How to implement for-else and foreach-else in C# similar to Python's for-else and while-else?如何在 C# 中实现类似于 Python 的 for-else 和 while-else 的 for-else 和 foreach-else?
【发布时间】:2011-09-26 16:38:22
【问题描述】:

Python 的 forwhile 循环包含一个可选的 else 子句,如果循环正常退出(ie没有 break 语句)。例如,在 Python 中,您可以编写代码:

for x in range(3):
    print(x)
else
    print("The loop exited normally")

输出将是:

0
1
2
The loop exited normally

您将如何在 C# 中完成类似的操作,以便编写如下代码:

for (int i = 0; i < 3; i++)
{
    Console.WriteLine(x);                  
}
else
    Console.WriteLine("The loop exited normally");

【问题讨论】:

  • 除非你真的给出了这些神奇构造的完整定义,否则这个问题是不真实的。
  • 听起来很可疑Pythonic...
  • 给我们你想要使用这些结构的场景,我敢打赌你总是可以在你的 for 或 foreach 循环周围放置一个 if - else。
  • 我怀疑伪代码是 leppie 关于“完整定义”的想法......

标签: c# for-loop foreach if-statement


【解决方案1】:

如果您指的是the for-else and while-else constructs in Python,那么有一个基本的IEnumerable&lt;T&gt; 扩展方法可以模拟this article 中描述的foreach-else,具有以下实现:

public static void ForEachElse<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource, bool> action, Action @else)
{
    foreach (var i in source)
    {
        if (!action(i))
        {
            return;
        }
    }
    @else();
}

【讨论】:

    【解决方案2】:

    谷歌搜索给了我:http://www-jo.se/f.pfleger/.net-for-else

    public static void ForEachElse<TSource>(
    this IEnumerable<TSource> source,
    Func<TSource>,
    bool action,
    Action @else
    )  // end of parameters
    {
    foreach (var i in source)
      {
        if (!action(i))
          {
            return;
          }
      }
       @else();
    }
    

    【讨论】:

      【解决方案3】:

      foreach-else 的 Python 构造如下:

      foreach( elem in collection )
      {
          if( condition(elem) )
              break;
      }
      else
      {
          doSomething();
      } 
      

      只有在foreach循环期间没有调用break时才执行else

      C# 等价物可能是:

      bool found = false;
      foreach( elem in collection )
      {
          if( condition(elem) )
          {
              found = true;
              break;
          }
      }
      if( !found )
      {
          doSomething();
      }
      

      来源:The Visual C# Developer Center

      【讨论】:

        【解决方案4】:

        当然:

        • 使用其他发帖人的一个奇特建议

        • 使用执行循环的方法,而不是break,可以return避免执行循环下面的代码

        • 使用您可以在break 之前设置的布尔变量,并在循环之后对其进行测试

        • 使用goto 代替break

        如果你问我,这是一个奇怪的模式。 “Foreach”总是开始,所以“else”这个词在那里没有意义。

        【讨论】:

        • Aaargh - 转到。真的吗?
        • @JonEgerton,虽然我不会在这里完全使用 goto,但我也不会谴责它。 python for-else 构造只是goto 的一个特例。如果您滚动自己的 goto,那么您仍然拥有相同的流控制,因此不会对您的代码进行标记。麻烦的是,您可能会在以后的某些更改中不小心将其转义。
        • 我几乎喜欢goto的建议,除了它允许其他代码进入它。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2019-12-08
        • 2016-10-28
        • 2022-01-10
        • 2012-10-15
        • 2017-11-27
        • 2011-03-18
        • 2012-02-02
        相关资源
        最近更新 更多