【问题标题】:How to break out of nested for loops [duplicate]如何打破嵌套的for循环[重复]
【发布时间】:2011-10-22 18:04:05
【问题描述】:

可能的重复:
Breaking out of a nested loop
How to break out of 2 loops without a flag variable in C#?

您好,我有一个具有嵌套循环的函数。满足条件后,我想跳出嵌套循环。代码如下所示:

foreach (EmpowerTaxView taxView in taxViews)
            {
                foreach (PayrollEmployee payrollEmployee in payrollEmployees)
                {
                    //PayStub payStub = payrollEmployee.InternalPayStub;

                    IReadOnlyList<PayrollWorkLocation> payrollWorkLocations =  payrollEmployee.PayrollWorkLocations;

                    foreach (PayrollWorkLocation payrollWorkLocation in payrollWorkLocations)
                    {
                        Tax tax = GetTaxEntity(payrollWorkLocation, taxView.BSITypeCode, taxView.BSIAuthorityCode,
                                               paidbyEr, resCode);

                        if (tax != null && tax.Rate.HasValue)
                        {
                            taxRate = tax.Rate.Value;
                            break;
                        }
                    }
                }
            }

不幸的是,break 仅来自一个循环。我想摆脱整个事情。拜托,我知道有些人建议 goto: 声明。我想知道有没有其他方法,比如写一些 LINQ 查询来达到同样的效果。

非常感谢任何想法和建议!

【问题讨论】:

  • @Henk 这几乎和地区一样邪恶。
  • @Yuny:迷信。正确使用它们。

标签: c# loops


【解决方案1】:

有两个选项建议自己作为退出的方式,而无需额外的标志变量来指示“你也应该跳出内部循环”。 (我个人真的不喜欢有这样的变量。

一种选择是将所有这些代码提取到一个单独的方法中 - 然后您可以从该方法返回。无论如何,这可能会提高您的代码可读性 - 这真的感觉它已经足够保证提取到一个单独的方法中了。

另一个明显的选择是使用 LINQ。这是我认为可行的示例:

var taxRate = (from taxView in taxViews
               from employee in payrollEmployees
               from location in employee.PayrollWorkLocations
               let tax = GetTaxEntity(location, taxView.BSITypeCode,
                                      taxView.BSIAuthorityCode,
                                      paidbyEr, resCode)
               where tax != null && tax.Rate.HasValue
               select tax.Rate).FirstOrDefault();

在我看来,这比许多 foreach 循环要干净得多。

请注意,我没有选择tax.Rate.Value - 只是tax.Rate。这意味着如果没有找到匹配的比率,结果将是“空”decimal?(或任何类型的tax.Rate),否则就是比率。所以你会有:

if (taxRate != null)
{
    // Use taxRate.Value here
}

【讨论】:

  • 谢谢!那就是我正在寻找的东西。我认为这可以用 LINQ 完成,我更喜欢 goto。
【解决方案2】:

您可以使用标志变量。

bool doMainBreak = false;
foreach (EmpowerTaxView taxView in taxViews)
{
    if (doMainBreak) break;
    foreach (PayrollEmployee payrollEmployee in payrollEmployees)
    {       
        if (doMainBreak) break;
        //PayStub payStub = payrollEmployee.InternalPayStub;

        IReadOnlyList<PayrollWorkLocation> payrollWorkLocations =  payrollEmployee.PayrollWorkLocations;

        foreach (PayrollWorkLocation payrollWorkLocation in payrollWorkLocations)
        {
            Tax tax = GetTaxEntity(payrollWorkLocation, taxView.BSITypeCode, taxView.BSIAuthorityCode,
                                   paidbyEr, resCode);

            if (tax != null && tax.Rate.HasValue)
            {
                taxRate = tax.Rate.Value;
                doMainBreak = true;
                break;
            }
        }
    }
}

【讨论】:

    【解决方案3】:

    好吧,你可以使用可怕的goto,重构你的代码,或者这样:

    // anon-method
    Action work = delegate
    {
        for (int x = 0; x < 100; x++)
        {
            for (int y = 0; y < 100; y++)
            {
                return; // exits anon-method
            }
        }
    };
    work(); // execute anon-method
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2012-11-30
      • 2010-10-13
      • 2015-03-03
      • 2013-03-09
      • 1970-01-01
      相关资源
      最近更新 更多