If I have the following code:
List<MyClass> list = GetList();
list.ForEach(i => i.SomeMethod());
and let's say SomeMethod()
throws an exception. Does ForEach
continue iterating, or does it just stop right there?
If it does terminate, is there any way to get the rest of the items in the collection to run their methods?
Yes, if an exception is thrown, the loop exits. If you don't want that behaviour, you should put exception handling into your delegate. You could easily create a wrapper method for this:
public static Action<T> SuppressExceptions<T>(Action<T> action)
{
return item =>
{
try
{
action(item);
}
catch (Exception e)
{
// Log it, presumably
}
};
}
To be honest, I would try to avoid this if possible. It's unpleasant to catch all exceptions like that. It also doesn't record the items that failed, or the exceptions etc. You really need to think about your requirements in more detail:
It would almost certainly be cleaner to create a separate method which used the normal foreach
loop instead, handling errors and collecting errors as it went. Personally I generally prefer using foreach
over ForEach
- you may wish to read Eric Lippert's thoughts on this too.
It will throw an error. You're also well on your way to reimplementing foreach
. How about just:
foreach (var item in list)
{
try
{
// dangerous thing with item
}
catch (Exception e)
{
// how do you want to log this?
}
}
This has the benefit of working in most versions of .NET and being obviously side-effectful. Of course, you can put this code directly in the ForEach
delegate, but I would only suggest that if it's going to be a method itself (rather than a lambda function).
A reasonable alternative is to create your own ForEachWithCatch
extension that captures all the exceptions and sends them back to the caller:
public static IEnumerable<Tuple<T,Exception>> ForEachWithCatch<T>(this IEnumerable<T> items, Action<T> action)
{
var exceptions = new List<Tuple<T,Exception>>();
foreach(var item in items)
{
try
{
action(item);
}
catch(Exception e)
{
exceptions.Add(Tuple.Create(item, e));
}
}
return exceptions;
}
This sends back an enumerable of each item that failed and it's corresponding exception.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With