As others have posted, you can't exit the loop in ForEach.
Are you able to use LINQ? If so, you could easily combine TakeWhile and a custom ForEach extension method (which just about every project seems to have these days).
In your example, however, List<T>.FindIndex would be the best alternative - but if you're not actually doing that, please post an example of what you really want to do.
As others have posted, you can't exit the loop in ForEach.
Are you able to use LINQ? If so, you could easily combine TakeWhile and a custom ForEach extension method (which just about every project seems to have these days).
In your example, however, List<T>.FindIndex would be the best alternative - but if you're not actually doing that, please post an example of what you really want to do.
There is no loop that one has access to, from which to break. And each call to the (anonymous) delegate is a new function call so local variables will not help. But since C# gives you a closure, you can set a flag and then do nothing in further calls:
bool stop = false;
myList.ForEach((a) => {
if (stop) {
return;
} else if (a.SomeCondition()) {
stop = true;
}
});
(This needs to be tested to check if correct reference semantics for closure is generated.)
A more advanced approach would be to create your own extension method that allowed the delegate to return false to stop the loop:
static class MyExtensions {
static void ForEachStoppable<T>(this IEnumerable<T> input, Func<T, bool> action) {
foreach (T t in input) {
if (!action(t)) {
break;
}
}
}
}
foreach (string s in sList)
{
if (s.equals("ok"))
return true;
}
return false;
Alternatively, if you need to do some other things after you've found the item:
bool found = false;
foreach (string s in sList)
{
if (s.equals("ok"))
{
found = true;
break; // get out of the loop
}
}
// do stuff
return found;
Use break; and this will exit the foreach loop
c# - How can i exit the LINQ foreach loop when some condition fails - Stack Overflow
C# Break out of foreach loop after X number of items - Stack Overflow
Linq return whole method not just the filter.
c# - ForEach() : Why can't use break/continue inside - Stack Overflow
As commented, just use a normal foreach construct. You gain nothing by using the ForEach method with a lambda. If anything it's even a little less readable.
foreach (var number in myList)
{
if (number.Value == null)
{
isError = true;
break;
}
else if (a.SomeCondition())
{
//Do some execution
}
}
You are certainly better off with a foreach statement so you can actually accomplish this. That said you could use a single bool to effectively skip the remaining iterations.
var keepGoing = true;
myList.ForEach(number =>
{
if (keepGoing)
{
if (number.Value == null)
{
isError = true;
keepGoing = false;
}
else if (a.SomeCondition())
{
//Do some execution
}
}
});
I recommend reading through this thread as well. List ForEach break
int processed = 0;
foreach(ListViewItem lvi in listView.Items)
{
//do stuff
if (++processed == 50) break;
}
or use LINQ
foreach( ListViewItem lvi in listView.Items.Cast<ListViewItem>().Take(50))
{
//do stuff
}
or just use a regular for loop (as suggested by @sgriffinusa and @Eric J.)
for(int i = 0; i < 50 && i < listView.Items.Count; i++)
{
ListViewItem lvi = listView.Items[i];
}
Why not just use a regular for loop?
for(int i = 0; i < 50 && i < listView.Items.Count; i++)
{
ListViewItem lvi = listView.Items[i];
}
Updated to resolve bug pointed out by Ruben and Pragmatrix.
Hey guys, noob question but how do i return from inside a Linq For loop. I have something like this
recipe.RequiredItem.ToList().ForEach(item => {
if (!save.PlayerStall.Inventory.ContainsKey(item.Key.UUID)){
//Notification code
return;
}
});The issue is that the return seems to Only kick out of the loop not the whole method so the code under this which then actually crafts the item runs anyway. I have thought about just a bool at the top called CanCraft or something and setting that so when the loop exists I check if can craft and return then. but that seems wrong, I feel Linq must have a way to fully escape right!???
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.
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.
I would rewrite this:
while (foo() == true)
{
foreach (var x in xs)
{
if (bar(x) == true)
{
//"break;" out of this foreach
//AND "continue;" on the while loop.
}
}
//If I didn't continue, do other stuff.
DoStuff();
}
as
while (foo()) // eliminate redundant comparison to "true".
{
// Eliminate unnecessary loop; the loop is just
// for checking to see if any member of xs matches predicate bar, so
// just see if any member of xs matches predicate bar!
if (!xs.Any(bar))
{
DoStuff();
}
}
while (something)
{
foreach (var x in xs)
{
if (something is true)
{
//Break out of this foreach
//AND "continue;" on the while loop.
break;
}
}
}
I want to avoid doing this:
foreach (string name in names)
{
if(name != "The name I want to skip over")
{
//The rest of my code
}
}and instead do something like this:
foreach (string name in names)
{
if(name == "The name I want to skip over")
//exit current loop;
//The rest of my code
}I am working with some objects that have a number of nested properties including lists which have other List<ObjA>. When trying to read the lowest level of data I get this:
foreach (ISOTLG tlg in isoxml.TimeLogs.Values)
{
foreach(TLGDataLogLine dll in tlg.Entries)
{
foreach(TLGDataLogEntry entry in dll.Entries)
{
Console.WriteLine($"POS EAST: {dll.PosEast} POS NORTH:{dll.PosNorth}");
}
}
}
Is there a prettier way or better way to do this? If I go all the way down Ill have 8 nested foreach loops
A) ForEach is not LINQ, it is a method on List<T>.
B) Just use foreach.
C) return will do it.
Edit
Just to clarify, what you are doing is providing a method that will be called for each entry in the list. return will just apply to the method for that member. The rest of the members in the list will still call the method.
Personally, I would just use a standard foreach loop instead of List<T>.ForEach.
In this case, you can invert the condition (to avoid the code in that case) or call return, since your goal is to use a continue statement. However, if you wanted to break, this would not work. That being said, there are quite a few other reasons to avoid List<T>.ForEach, so I would consider switching this to a normal foreach statement.