Question

Since ForEach() method loop through all a list members, Why cant use a break/continue clause while i can use them inside a normal foreach loop

lstTemp.ForEach(i=>
 {
   if (i == 3)
   break;
   //do sth
 }
);

Error:

"No enclosing loop out of which to break or continue"

Was it helpful?

Solution

Because ForEach is a method and not a regular foreach loop. The ForEach method is there for simple tasks, if you need to break or continue just iterate over lstTemp with a regular foreach loop.

Usually, ForEach is implemented like this:

public static ForEach<T>(this IEnumerable<T> input, Action<T> action)
{
  foreach(var i in input)
    action(i);
}

As it is a normal method call, action doesn't know anything about the enclosing foreach, thus you can't break.

OTHER TIPS

Presumably because you're using a lambda and the contents of the lambda are ignorant to the fact that it's being used inside a loop.

rather than using a break, perform a filter first like this (it may not be the exact filter you need, but illustrates the point)

lstTemp.Where(i => i!= 3).ForEach(i=> // do sth);

return will act as continue in ForEach.

Example:

var list = new List<int>() {1, 2, 3, 4};
list.ForEach(i => 
    {
        if (i == 3)
            return;
        Console.WriteLine(i);
    }
);

Prints 1, 2, 4.

3 - skipped.

To iterate only part of the items and emulate the break perfectly, you can use FirstOrDefault:

lstTemp.FirstOrDefault(i=>
 {
   if (i == 3)
       return true;

   //do stuff

   return false;
 }
);

For list with 100000 items, if the 10th item is 3 it will iterate only 10 times, using the Where solution will work, but iterate the whole list first.

The way I'd explain it is this: ForEach is a method, not a language feature. The C# foreach construct is a feature of the language within which the other language constructs break and continue are permitted.

I would also point out (not trying to judge, just making an observation) that this is a good example of why some developers object to the use of a ForEach method: it doesn't really save typing in this simple case, it requires one more redirection than necessary, and it doesn't have all the functionality of foreach anyway.

In my opinion the main scenario in which a ForEach method makes sense is as an extension on IEnumerable<T>--to put at the end of a chain of method calls. It seems (to me) a bit strange that they added it to List<T>.

break and continue are C# language keywords that require compiler support. ForEach, to the C# compiler, is just a method.

Because ForEach is a method and not a regular foreach loop is need iterate over lstTemp with a regular foreach loop in case break, but in case continue use return inside the ForEach method.

var lstTemp = new List<int>() {1, 2, 3, 4};
lstTemp.ForEach(i=>
{
     if (i == 3) return;
     //do sth
     Console.WriteLine(i);
});

Output: 1, 2, 4

Because you delegate an action for each item in the list.

You can write a extension method "ForEachWhile" that takes a Function<T, bool> and stops when false.

i used it

        list.ForEach((item) =>
        {
            if( isBreak == false ) do
            {
                if (isContinue)
                    break;

                // TODO
            } while (false); }
        });
Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top