Cannot we use break statement in a lambda(C#3.0)
Consider this
List<int> intList = new List<int> { 1, 2, 3, 4, 5, 6 };
开发者_如何学运维 int j = 0;
intList.ForEach(i =>
{
if (i.Equals(1))
{
j = i;
break;
}
}
);
Throwing error: No enclosing loop out of which to break or continue
But the below works
foreach(int i in intList)
{
j = i; break;
}
Why so. Am I making any mistake.
Thanks
Keep in mind that the purpose of the ForEach method is to call the lambda method you pass to it on each item in the list. If you need to break out of a loop as part of your loop processing, you have to use a classic loop.
At the risk of being modded down for "going outside of the scope of the question", I'm going to ask what it is the OP is really trying to accomplish.
The code in question is trying to determine if the integer (1) exists anywhere in the list. But it seems clear to me that the code above is just a demonstration, not the actual problem.
Using "ForEach" to iterate over the list to determine if something is in the list is the wrong way of going about this. Instead, using one of the many "Find" functions is the better approach.
For example, going along with the OP's original code:
j = intList.Find(i => i.Equals(1));
This would do exactly the same thing as the above proposed code. It would iterate over the list, (and if possible) return the lambda matched value to "j" and break early.
intList.Exists(i => i.Equals(1));
Would effectively do the same thing. It would iterate over the list and return a TRUE if it was able to find if 1 exists and "break" early. (otherwise it iterates over the whole list and returns FALSE.)
intList.FindIndex(i => i.Equals(1));
Would return the Index position of the FIRST instance that matches the lambda. (again breaking early if possible)
intList.FindAll(i => i.Equals(1));
Returns a sub-list of all the items in the intList that match the lambda expression. (naturally this has to iterate over the whole list, regardless...)
Newbie: Is there a reason why you cannot use any of these built-in methods? Just curious, as I'd like to help.
Cheers.
The ForEach
method is not a real foreach
loop. You can simulate the effect by throwing an exception inside the lambda and catching it outside the call to ForEach
.
The break statement only works in the same function scope as the foreach statement. The lambda starts a new function scope, thus the break does not work.
You can use the SkipWhile()
and Take()
extension methods to mimic what you're doing, but it isn't good or readable...
public void SO2857489()
{
var intList = new List<int> {1, 2, 3, 4, 5, 6};
var j = 0;
intList.SkipWhile(i => i != 1).Take(1).ToList().ForEach(i => j = i);
Console.WriteLine(j);
}
The SkipWhile()
here does the job of your if (i.Equals(1))
statement and the Take(1)
does the job of the break
. Like I said, it isn't pretty.
精彩评论