Если в списке возникает исключение.ForEach, останавливается ли итерация?

Если у меня есть следующий код:

List<MyClass> list = GetList();
list.ForEach(i => i.SomeMethod());

и скажем SomeMethod() выдает исключение. Делает ForEach продолжить итерацию или просто остановиться?

если он завершается, есть ли способ заставить остальные элементы в коллекции запускать свои методы?

3 ответов


да, если возникает исключение, цикл завершается. Если вы не хотите такого поведения, вы должны поместить обработку исключений в свой делегат. Вы мог бы легко создать метод обертки для этого:

public static Action<T> SuppressExceptions<T>(Action<T> action)
{
    return item =>
    {
        try
        {
            action(item);
        }
        catch (Exception e)
        {
            // Log it, presumably
        }
    };
}

честно говоря, я бы попробовать чтобы избежать этого, если возможно. Неприятно ловить все исключения, как, что. Он также не записывает элементы, которые не удалось, или исключения и т. д. Вам действительно нужно подумать о ваших потребностей в более подробно:

  • вам нужно собрать неудачные элементы?
  • вам нужно собрать исключений?
  • какие исключения вы хотите поймать?

было бы почти наверняка чище создать отдельный метод, который использовал бы нормальный цикл, обработка ошибок и сбор ошибок по мере их возникновения. Лично я вообще предпочитаю использовать foreach над ForEach - вы можете прочитать мысли Эрика Липперта на этом тоже.


он выдаст ошибку. Вы также хорошо на вашем пути к реорганизации foreach. Как насчет просто:

foreach (var item in list)
{
    try
    {
        // dangerous thing with item
    }
    catch (Exception e)
    {
        // how do you want to log this?
    }
}

в этом есть выгода работать в большинстве версий .Чистая и явно боковой effectful. Конечно, вы можете поместить этот код непосредственно в ForEach делегат, но я бы только предположить, что если это будет сам метод (а не лямбда-функция).


разумной альтернативой является создание собственного


Если SomeMethod реализовал блок try-catch, затем foreach продолжит

void SomeMethod()
{
  try
  {
    //Some operation on i 
  }
  catch(Exception ex)
  {
  }
}

но если нет, то foreach сломается.

один, что делать это так

list.ForEach(i => 
     {
         try
         {
             i.SomeMethod();
         }
         catch(Exception ex)
         {
         }
     });

но всегда хорошо иметь нулевые блоки try-catch в вашем коде. Иначе вы никогда не найдете виновника.