问题
Does anyone know if it is possible to exit a generic ForEach that uses lambda? e.g.
someList.ForEach(sl =>
{
if (sl.ToString() == "foo")
break;
// continue processing sl here
// some processing code
}
);
This code itself won't compile. I know I could use a regular foreach but for consistency I want to use lambda.
Many thanks.
回答1:
Sure. But first, note that I recommend against this; I say that a sequence operator should not have a side effect, and a statement should have a side effect. If you're doing something in that ForEach lambda, then make it a statement in the body of a foreach loop rather than making it look like a sequence operator.
That said, here's what you do. First, you write yourself a ForEach that works on arbitrary sequences, not just lists:
public static void ForEach<T>(this IEnumerable<T> sequence, Action<T> action)
{
foreach(var item in sequence) action(item);
}
And now you write your break like this:
someList
.TakeWhile(x=>x.ToString() != "foo")
.ForEach(sl=>
{/*your action here*/});
回答2:
From MSDN
The following rules apply to variable scope in lambda expressions:
snip
A lambda expression cannot contain a goto statement, break statement, or continue statement whose target is outside the body or in the body of a contained anonymous function.
Don't know if that helps given the code you posted. The relevant quote is from the end of the MSDN article.
回答3:
Warning: the code below is not to be taken seriously and is provided for entertainment purposes only!
You can 'simulate' a continue with an early return like this:
Enumerable.Range(1, 20)
.ForEach(n =>
{
if (n == 10) return;
Console.WriteLine("This is not 10: {0}", n);
});
That said, I think that side effects within lambda's are a sign that you're doing it wrong. Use a proper foreach instead. Or something like TakeWhile, as Eric kindly demonstrated already.
回答4:
How about this?
Enumerable.Range(1, 10)
.Where(x => x % 2 != 0)
.ToList()
.ForEach(x => Console.WriteLine(x));
来源:https://stackoverflow.com/questions/2249420/c-sharp-exit-generic-foreach-that-use-lambda