2011-01-06 5 views
2


J'aurais une autre question que je ne trouve pas de réponse. Je sais que l'ordre des blocs de capture est du plus dérivé au plus général.
Mais je ne comprends pas pourquoi je peux avoir ce (pourquoi ce travail de commande? FormatException est dérivé d'exception pour son plus générale, non?)Quelles sont les exceptions les plus dérivées?

catch(formatException) 
//this is derived from Exception 

catch(OutoFMemoryException) 
// this is derived from ArithmeticException whic is derived from Exception 
+0

C'est le plus spécifique au général. Donc, si vous aviez affaire à un code concernant SQL, vous attraperiez les exceptions SQL avant d'attraper tout le 'Exception' – codingbadger

Répondre

1

Pas nescessary, même si OverflowException dérive de ArithmeticException leur plus le dénominateur commun est Exception.

Vous pouvez le voir comme une sorte de structure arborescente, où FormatException et OverflowException est sur les différents côtés de l'arbre. Si OverflowException hérité de FormatException la situation serait différente, mais ce n'est pas le cas.

De même, vous pouvez les avoir dans un ordre différent mais cela ne sert à rien puisque si vous avez une exception plus générale, il va d'abord attraper toutes les exceptions en dessous.

+0

Merci, cependant je ne l'obtiens toujours pas entièrement .. Si toutes les exceptions héritent de la classe Exception, qui sont plus dérivés? – Loj

+0

@Loj: Je suis d'accord que dérivé peut être difficile à comprendre car pour moi, il semble que le mauvais mot à utiliser. Pensez-y comme spécifique à général à la place. Et vous devez aussi faire dans le contexte du plus petit dénominateur commun («Exception» dans votre cas). 'OverflowException' est aussi spécifique que' ArithmeticException' dans le contexte de 'Exception'. Cela a-t-il plus de sens? –

0

Cela fonctionne sur la hiérarchie et OverExceptionExceptiona et FormatException sont sur des branches différentes, et partagent la classe Exception commune seulement.

2

Le CLR passe à travers les blocs d'arrêt dans l'ordre indiqué.

S'il trouve une instruction catch avec un type d'exception qui correspond à l'exception en cours ou une exception qui hérite de l'exception en cours, ce bloc sera appelé.

1

Cela dépend également du type de l'exception lancée qui déterminera le bloc catch appelé. Puisque vous avez un attrapé pour FormatException défini, alors si un FormatException est lancé, il sera attrapé par cette capture seulement si la capture Exception n'est pas définie avant elle. Si vous n'avez pas défini la capture FormatException, une capture Exception traitera le FormatException car elle dérive de Exception.

1

L'instruction try-catch consiste en un bloc try suivi d'une ou de plusieurs clauses catch, qui spécifient des gestionnaires pour différentes exceptions.

Lorsqu'une exception est levée, Common Language Runtime (CLR) recherche l'instruction catch qui gère cette exception. Si la méthode en cours d'exécution ne contient pas un tel bloc catch, le CLR regarde la méthode qui a appelé la méthode en cours, et ainsi de suite la pile d'appels.

Si aucun bloc catch n'est trouvé, le CLR affiche un message d'exception non géré et arrête l'exécution du programme.

Au-dessus trouvé @msdn

Le CLR arrête au premier bloc catch qui peut gérer l'exception. Celui qui vient en premier dans la liste.

0

Le point est sous-classe viendra d'abord, puis la classe de base

+0

Oui, donc je pensais que si ArithmeticException est dérivé de Exception, sa sous-classe. Et OverflowException est dérivé de celui-ci. – Loj

2

Vous devez aller de l'exception la plus spécifique à l'exception la plus générale.

Par exemple, dans le code ci-dessous:

int x = 4/(1 - 1); 

Vous obtiendrez une exception de type DivideByZeroException, qui est un ArithmeticException, ce qui est une exception.

Alors, comment l'utiliseriez-vous?

Lorsque vous savez que vous pouvez obtenir certains types d'erreurs, vous pouvez mettre un code spécifique lorsque chacun d'entre eux se produit.

Si vous savez que vous pouvez obtenir une exception DivideByZeroException, vous placez un bloc catch pour cela, et traitez-le comme vous le devriez. Et vous devez également ajouter une prise pour un type d'exception plus générale:

try 
{ 
    int x = 4/(1 - 1); 
    // More Stuff 
} 
catch(DivideByZeroException ex) 
{ 
    // Here we know we got an exception on that division 
} 
catch(Exception ex) 
{ 
    // Here we know something went wrong on that "more stuff" 
} 

Vous pouvez le rendre plus facile à résoudre les problèmes de cette façon.

1

Utilisez cette partie de code par exemple. Vous devez toujours utiliser l'exception la plus spécifique en premier, puis utiliser l'exception la plus générale à la fin. Ou je crois que je peux dire comme vous l'avez dit - L'exception la plus dérivée en premier.

Dans ce cas, le premier bloc catch captures déjà toutes les exceptions de ce ou d'un type super (System.Exception) ». Ceci est la raison de l'ordre d'exception.

try 
{ 
throw new formatException(); 
} 


catch(Exception ex) 
{ 
    <...> 
} 
catch(formatException ex) 
{ 
    <...> 
} 

Modifier -

Si vous regardez la hiérarchie d'héritage de la classe FormatException -

System.Exception 
    System.SystemException 
     System.FormatException 

et la hiérarchie d'héritage de la classe OutOfMemoryException est -L'ordre de préséance des exceptions n'apparaît dans l'image que si vous avez des blocs catch avec des classes d'exception qui sont soit des classes de base, soit des classes dérivées l'une de l'autre.

Par exemple. si vous avez deux blocs catch - FormatException et Exception, vous devrez vous soucier de l'ordre des blocs de capture car la classe FormatException hérite de la classe Exception. Si le bloc catch Exception est placé avant le bloc catch FormatException, chaque exception est interceptée par le bloc catch Exception (même une exception de format). Si vous avez le bloc catch FormatException avant le bloc catch Exception, une exception de format est interceptée par le bloc catch FormatException spécifique, mais toutes les autres exceptions sont interceptées par le bloc catch Exception. Mais, si vous avez deux blocs catch tels que FormatException et OutOfMemoryException. Alors vous n'avez pas besoin de vous soucier de l'ordre car ces deux classes ne sont pas la base ou dérivées les unes des autres. Donc, ce ne sont que des exceptions spécifiques.

Ainsi, vous pouvez soit -

try 
{ 
throw new formatException(); 
} 
catch(OutOfMemoryException ex) 
{ 
    <...> 
} 
catch(FormatException ex) 
{ 
    <...> 
} 

Ou

try 
{ 
throw new formatException(); 
} 
catch(FormatException ex) 
{ 
    <...> 
} 
catch(OutOfMemoryException ex) 
{ 
    <...> 
} 

Il ne serait pas une différence parce que, peu importe ce que l'ordre est le FormatException est toujours pris par le FormatException spécifique attraper le bloc.C'est pareil pour OutOfMemoryException. J'espère que cela répond à votre question.

+0

Oui, je comprends que FormatException est dérivé de l'exception, donc il a la priorité. Mais qu'est-ce qui aurait préséance avant même FormatException? – Loj

+0

Vérifiez ma réponse mise à jour. – pavanred

0

@Loj, vous pouvez penser conceptuellement des déclarations de capture comme une instruction switch (on ne peut pas écrire une instruction switch comme ça, mais quand même):

switch (caughtException) 
{ 
    case (caughtException is FormatException):...; 
    case (caughtException is OverflowException):...; 
    case (caughtException is Exception):...; 
    etc. 

Le premier type qui répond à la « est "vérifier sera celui qui gère votre exception. C'est pourquoi vous devez être conscient de l'ordre de vos blocs de capture. Les blocs de captures sont spécifiés du plus spécifique au plus général car c'est le meilleur moyen de s'assurer que nous ne nous sommes pas confondus.

Dans votre exemple, OutOfMemoryException est « plus éloignée » de l'exception que FormatException, mais cela ne crée pas un problème parce que le chèque caughtException is FormatException renvoie false, et nous passons à la possibilité suivante.

Questions connexes