2010-10-27 10 views
17

Ceci est un peu abstrait, mais existe-t-il un moyen possible de lancer une exception et de l'entrer dans plusieurs blocs catch? Par exemple, s'il correspond à une exception spécifique suivie d'une exception non spécifique.Puis-je exécuter plusieurs blocs Catch?

catch(Arithmetic exception) 
{ 
    //do stuff 
} 
catch(Exception exception) 
{ 
    //do stuff 
} 

Répondre

30

Il est parfaitement acceptable d'avoir plusieurs blocs de saisie de types différents. Cependant, le comportement est que le premier bloc candidat gère l'exception.

Il n'entrera pas dans les DEUX blocs catch. Le premier bloc catch qui correspond au type d'exception gérera cette exception spécifique, et pas d'autres, même s'il est renvoyé dans le gestionnaire. Les suivants seront ignorés une fois qu'une exception entre dans un bloc catch.

Afin d'avoir une exception pris dans les deux blocs, vous devez soit des blocs de nid comme si:

try 
{ 
    try 
    { 
     // Do something that throws ArithmeticException 
    } 
    catch(ArithmeticException arithException) 
    { 
     // This handles the thrown exception.... 

     throw; // Rethrow so the outer handler sees it too 
    } 
} 
catch (Exception e) 
{ 
    // This gets hit as well, now, since the "inner" block rethrew the exception 
} 

Alternativement, vous pouvez filtrer dans un gestionnaire d'exception générique en fonction du type d'exception spécifique.

+2

L'imbrication fonctionne bien pour les hiérarchies simples à un seul niveau, mais peut s'avérer très difficile si vous avez un code partagé qui doit s'exécuter dans plusieurs cas d'exception. Ce n'est pas un désaccord avec l'approche, mais une observation que ce n'est pas toujours approprié. – tvanfosson

+0

@tvanfosson: Oui, c'est pourquoi j'ai aussi ajouté l'option de filtrage. Votre option est très belle aussi. –

18

Non. Il n'est pas possible d'exécuter le code dans les deux blocs catch pour une seule exception.

Je refactoriserais probablement le code dans le bloc d'exception générique en quelque chose qui peut être appelé depuis l'un ou l'autre.

try 
{ 
    // blah blah blah 
{ 
catch(Arithmetic ae) 
{ 
    HandleArithmeticException(ae); 
    HandleGenericException(ae); 
} 
catch(Exception e) 
{ 
    HandleGenericException(e); 
} 
1

Vous ne pouvez pas avoir plus d'un bloc d'exception gérer la même exception. Mais ce que vous pouvez faire est attraper l'exception générale, essayez alors de jeter au plus spécifique, comme ceci:

catch (Exception exception) 
{ 
    var aex = exception as ArithmeticException 
    if (aex != null) 
    { 
     // do stuff specific to this exception type 
    } 
    // then do general stuff 
} 
0

Ceci est connu comme le filtrage d'exception et n'est pas pris en charge en C# (on me dit c'est possible dans VB.NET). Un travail consiste à attraper l'exception générale, puis à vérifier le type d'exception dans le bloc catch et à effectuer un traitement spécifique avant de continuer avec le reste du bloc.

1

Comme d'autres l'ont dit, l'exception sera interceptée par le bloc catch le plus spécifique.

Cela amène une frustration du mien, mais avec la gestion des exceptions. Je voudrais que vous pourriez faire quelque chose comme

catch (ArgumentNullExcpetion, ArugmentOutOfRangeException ex) 
{ 

} 

Au lieu d'avoir à faire

catch (ArgumentNullExcpetion e) 
{ 
} 
catch (ArugmentOutOfRangeException outOfRange) 
{ 
} 

Je comprends le raisonnement contre ce que vous faites probablement différentes choses pour différentes exceptions, mais parfois, je veux les combiner.

+1

Les deux ne dérivent pas de ArgumentException - si vous voulez vraiment faire la même chose pour les deux, il suffit d'attraper ArgumentException. Si vous souhaitez capturer uniquement les exceptions enfants, vous devez filtrer (et relancer) ArgumentException à l'aide de la logique conditionnelle. Votre point général est bon, mais ce n'est pas le meilleur exemple. Peut-être que quelque chose comme ValidationException (erreur de modèle) et SqlException (violation de contrainte) où ils ne sont pas dans la même hiérarchie est un meilleur exemple. – tvanfosson

+1

Je ne pense pas que votre 100% à droite quand vous dites "l'exception sera attrapé par le bloc catch le plus spécifique" Cela dépend également de l'ordre. Donc, si vous avez une prise tout d'abord tout tombera toujours dans ce même si vous avez des plus spécifiques après elle – jon

+0

tvanfosson. Bonne prise. Je viens de faire cet exemple à la volée. Vous avez raison, je pourrais attraper l'exception générale des parents dans ce cas. Mais ouais je voudrais un moyen d'attraper plusieurs types d'exceptions non apparentées dans un bloc catch –

2

Si vous utilisiez VB.NET, vous pourriez résumer votre gestionnaire d'erreurs dans l'exception Arithmetic en un appel de fonction ou de méthode qui renvoie toujours false.

Ensuite, vous pouvez écrire quelque chose comme:

Catch ex as Arithmetic When HandleArithmetic() 
Catch ex as Exception 

End Try 

Non que je préconiserais une telle utilisation, bien que je l'ai vu recommandé à des fins d'exploitation forestière avant. Je ne crois pas qu'il y ait un équivalent C#.

Questions connexes