If an exception is thrown in List <T> .ForEach, does the iteration stop?
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 keep repeating or just stop right there?
If it completes, is there a way to get the rest of the elements in the collection to run my methods?
Yes, if an exception is thrown, the loop ends. If you do not want this behavior, you should put exception handling in 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 } }; } Honestly, I will try to avoid this, if possible. It is unpleasant to catch all such exceptions. It also does not record inappropriate elements or exceptions, etc. You really need to consider your requirements in more detail:
- Do you need to collect failed elements?
- Do you need to collect exceptions?
- What exceptions do you want to catch?
It would be almost wise to create a separate method that would instead use a regular foreach , handling errors and collecting errors as they occur. Personally, I usually prefer to use foreach over foreach - you can read Eric Lippert's thoughts about this too .
He gives an error. You are also on the way to overriding foreach . How about just:
foreach (var item in list) { try { // dangerous thing with item } catch (Exception e) { // how do you want to log this? } } It makes sense to work in most versions of .NET and be clearly a side effect. Of course, you can put this code directly into the foreach delegate, but I would suggest that if it would be the method itself (and not the lambda function).
A reasonable alternative is to create your own ForEachWithCatch extension, which captures all exceptions and sends them 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; } Sends back the enumerated from each nonconforming element and the corresponding exception.
If your SomeMethod implemented a try-catch block, foreach will continue
void SomeMethod() { try { //Some operation on i } catch(Exception ex) { } } But if not, the foreach will break.
One way to do it this way
list.ForEach(i => { try { i.SomeMethod(); } catch(Exception ex) { } }); But it is always useful to have null try-catch blocks in your code. Otherwise, you will never find where the criminal is.