2

Possible Duplicates:
Breaking out of a nested loop
How to break out of 2 loops without a flag variable in C#?

Hello I have a function that has nested loops. Once the condition has been met, I want to break out of nested loops. The code is something like this below:

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;
                        }
                    }
                }
            }

Unfortunately, break comes out of only one loop. I want to break out of the whole thing. Please, I know some people have suggested goto: statement. I am wondering is there any other way around, such writing some LINQ queries to the same effect.

Any ideas and suggestions are greatly appreciated !

Community
  • 1
  • 1
SaiBand
  • 5,025
  • 15
  • 57
  • 76

3 Answers3

4

Two options suggest themselves as ways of getting out without having an extra flag variable to indicate "you should break out of the inner loop too". (I really dislike having such variables, personally.

One option is to pull all of this code into a separate method - then you can just return from the method. This would probably improve your code readability anyway - this really feels like it's doing enough to warrant extracting into a separate method.

The other obvious option is to use LINQ. Here's an example which I think would work:

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();

That looks considerably cleaner than lots of foreach loops to me.

Note that I haven't selected tax.Rate.Value - just tax.Rate. That means the result will be a "null" decimal? (or whatever type tax.Rate is) if no matching rates are found, or the rate otherwise. So you'd then have:

if (taxRate != null)
{
    // Use taxRate.Value here
}
Jon Skeet
  • 1,421,763
  • 867
  • 9,128
  • 9,194
  • Thanks ! that was what I was looking. I thought this could be done with LINQ and I prefer that to goto. – SaiBand Aug 09 '11 at 14:01
2

Well, you could use the dreaded goto, refactor your code, or this:

// 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
0

You could use a flag variable.

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;
            }
        }
    }
}
fehays
  • 3,147
  • 1
  • 24
  • 43