tags:

views:

93

answers:

3
+4  Q: 

List ForEach break

is there a way to break out of the foreach extension method? The "break" keyword doesn't recognize the extension method as a valid scope to break from.

//Doesn't compile
Enumerable.Range(0, 10).ToList().ForEach(i => { System.Windows.MessageBox.Show(i.ToString()); if (i > 2)break; });

Edit: removed "linq" from question


note the code is just an example to show break not working in the extension method... really what I want is for the user to be able to abort processing a list.. the UI thread has an abort variable and the for loop just breaks when the user hits a cancel button. Right now, I have a normal for loop, but I wanted to see if it was possible to do with the extension method.

+6  A: 

It's probably more accurate to call this a List<T> Foreach vs. a LINQ one.

In either case though no there is no way to break out of this loop. Primarily because it's not actually a loop per say. It's a method which takes a delegate that is called inside a loop.

Creating a ForEach with break capability is fairly straight forward though

public delegate void ForEachAction<T>(T value, ref bool doBreak);
public static void ForEach<T>(this IEnumerable<T> enumerable, ForEachAction<T> action) {
    var doBreak = false;
    foreach (var cur in enumerable) {
        action(cur, ref doBreak);
        if (doBreak) {
            break;
        }
    }
}

You could then rewrite your code as the following

Enumerable.Range(0,10)
    .ForEach((int i,ref bool doBreak) => {
        System.Windows.MessageBox.Show(i.ToString()); 
        if ( i > 2) {doBreak = true;}
    });
JaredPar
+2  A: 

Why not use Where?

Enumerable.Range(0, 10).Where(i => i <= 2).ToList().ForEach(...)
Jay Bazuzi
+4  A: 

I recommend using TakeWhile.

Enumerable.Range(0, 10).TakeWhile(i => i <= 2).ToList().ForEach(i => MessageBox.Show(i.ToString()));

Or, using Rx:

Enumerable.Range(0, 10).TakeWhile(i => i <= 2).Run(i => MessageBox.Show(i.ToString()));
Stephen Cleary