2012-05-17 20 views

Respuesta

13

Sí, si se produce una excepción, el ciclo se cierra. Si no desea ese comportamiento, debe poner el manejo de excepciones en su delegado. Usted podría crear fácilmente un método de envoltura para esto:

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

Para ser honesto, me tratar de evitar esto si es posible. Es desagradable detectar todas las excepciones de esa manera. También no registra los elementos que fallaron, o las excepciones etc Usted realmente necesita para pensar acerca de sus necesidades con más detalle:

  • ¿Es necesario recoger los elementos fallidos?
  • ¿Necesita recoger las excepciones?
  • ¿Qué excepciones desea atrapar?

Sería casi seguro que será más limpio para crear un método independiente que utiliza el foreach rizo en su lugar, el manejo de errores y recoger los errores a medida que avanzaba. Personalmente, generalmente prefiero usar foreach sobre ForEach - puede leer Eric Lippert's thoughts on this too.

+0

he actualizado el título de mi pregunta, gracias jon – Jason

+0

@Jason: Righto - se deshace de la primera frase. He editado mi respuesta ... –

+0

gracias por esta respuesta bien pensada y muy informativa. – Jason

3

Se arrojará un error. También está en camino de volver a implementar foreach. ¿Qué tal solo:

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

Esto tiene el beneficio de funcionar en la mayoría de las versiones de .NET y obviamente tiene efectos secundarios. Por supuesto, puede poner este código directamente en el delegado ForEach, pero solo sugeriría que sea un método en sí mismo (en lugar de una función lambda).


Una alternativa razonable es crear su propia ForEachWithCatch extensión que captura todas las excepciones y los envía de vuelta a la persona que llama:

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; 
} 

Esto envía de vuelta un enumerable de cada elemento que falló y su correspondiente excepción.

0

Si el bloque try-catch SomeMethod ha puesto en marcha a continuación foreach continuará

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

Pero si no, entonces foreach se romperá.

Uno lo de hacerlo de esta manera es

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

Pero siempre es bueno tener cero bloques try-catch en su código. De lo contrario, nunca encontrarás dónde está el culpable.

Cuestiones relacionadas