12
votes

.NET et c # Exceptions. Qu'est-ce qu'il est raisonnable d'attraper

Disclaimer, je viens d'un fond de Java. Je ne fais pas beaucoup de c #. Il y a beaucoup de transfert entre les deux mondes, mais bien sûr, il y a des différences et que l'on est dans la voie à laquelle des exceptions ont tendance à être pensées.

J'ai récemment répondu à une question C # suggérant que sous certaines circonstances, il est raisonnable de le faire: p> xxx pré>

(les raisons pour lesquelles sont immatérielles). J'ai eu une réponse que je ne comprends pas tout à fait: P>

jusqu'à .net 4.0, c'est très mauvais d'attraper Exception. Cela signifie que vous attrapez divers erreurs fatales de bas niveau et déguisement Bugs. Cela signifie également que dans l'événement d'une sorte de corruption qui déclenche une telle exception, tout ouvert enfin blocs sur la pile sera exécuté, donc même si le ColletReReportter Fuciding Thes pour se connecter et cesser de fumer, il ne peut même pas obtenir à ce point (les blocs enfin peuvent jeter à nouveau ou causer plus de corruption, ou supprimer quelque chose d'important de la disque ou base de données). P> BlockQuote>

Peut-être que je suis plus confus que je ne le réalise, mais je ne suis pas d'accord avec une partie de cela. S'il vous plaît, des autres personnes commenteront-elles. p>

  1. Je comprends qu'il y a beaucoup d'exceptions à faible niveau que nous ne voulons pas avaler. Ma fonction CommonExceptionHandler () pourrait raisonnablement retenir ceux-ci. Cela semble compatible avec Cette réponse à une question connexe. Ce qui dit "en fonction de votre contexte, il peut être acceptable d'utiliser les captures (...), à condition que l'exception soit remontée." Je conclus donc que l'utilisation de captures (exception) n'est pas toujours pervers, avalant silencieusement certaines exceptions est. P> li>

  2. la phrase "jusqu'à .net 4 Il est très mauvais d'attraper une exception" Qu'est-ce qui change de .NET 4? Est-ce une référence à AggregateException, qui peut nous donner de nouvelles choses à faire avec des exceptions que nous attrapons, mais je ne pense pas que la règle fondamentale "n'invalue pas". P> li>

  3. La phrase suivante réellement déroulantes être. Peut-être raison? P> LI> ol>

    Cela signifie aussi que dans l'événement d'une sorte de corruption qui déclenche une telle exception, tout ouvert enfin blocs sur la pile sera exécuté (les blocs enfin peuvent jeter à nouveau ou causer plus de corruption, ou supprimer quelque chose d'important de la disque ou base de données) p> blockQuote>

    Ma compréhension est que si un code de niveau inférieur avait p> xxx pré>

    et dans mon code, j'appelle Lowlevel (); P>

     try {
          lowLevel()
     } catch (Exception e) {
           exception handling and maybe rethrowing
     }
    


5 commentaires

Je suis d'accord avec vous à propos de # 3, mais je ne peux pas répondre définitivement dessus. Intéressé d'entendre aussi. Je sais qu'il y a quelques exceptions à exception que nous ne pouvons pas attraper ( msdn.microsoft. com / fr-nous / bibliothèque / ... ). Potentiellement l'affiche faisait référence à cela, dans le sens précédent à .net-2.0. Il semble que, si dans .net 2.0, ça va.


Si nous ne pouvons pas les attraper, alors mon bloc de capture ne peut-il pas faire du mal? :-) J'essaie de comprendre les situations où ce bloc de capture peut être activement endommager.


D'accord :) Vérifiez le lien cependant; Il dit en .NET <2, attrapant StackoverflowException est mauvais.


Merci, c'était un lien intéressant.


Je suis d'accord avec @james et @keith; et je ne pense pas que la décision d'attraper une saveur d'exception a quelque chose à voir avec la dichotomie C # / Java


5 Réponses :


0
votes

Je pense que la réponse citée est fausse (ou peut-être signifiait-elle 2.0 au lieu de 4.0)? Cela me semble un peu fou.


0 commentaires

1
votes

juste à votre troisième question:

Si vous avez P>

nastyLowLevel() {
  doSomethingWhichMayCorruptSomethingAndThrowsException();
}

MyEvilCatcher() {
  try {
    nastyLowLevel();
  } catch (Exception e) {
    MyExceptionHandler(e);
  }
}

WiseCatcher() {
  try {
    MyEvilCatcher();
  } catch (LowLevelException e) {
    DoSomethingWiseSoFinnalyDontRuinAnything();
  } finally {
    DoSomethingWhichAssumesLowLevelWentOk();
  }
}


1 commentaires

Merci. Je suis d'accord avec votre philosophie. Je pensais que, en écrivant MyExceptionHandler () avec précaution, correctement, une fois que nous augmentons réellement nos chances de bien gérer. Le contexte était un chapitre écrit un grand nombre de blocs d'essai / attraper.



9
votes

En règle générale, vous ne devriez pas attraper des exceptions à moins que:

  1. Vous avez une exception spécifique que vous pouvez gérer et faire quelque chose. Cependant, dans ce cas, vous devriez toujours vérifier si vous ne devriez pas essayer de prendre votre compte et d'éviter l'exception en premier lieu.

  2. Vous êtes au niveau supérieur d'une application (par exemple l'interface utilisateur) et ne souhaitez pas que le comportement par défaut soit présenté à l'utilisateur. Par exemple, vous pouvez vouloir une boîte de dialogue d'erreur avec un message "s'il vous plaît envoyez-nous vos journaux" Message de style.

  3. Vous rejetez l'exception après avoir affaire à elle en quelque sorte, par exemple si vous réduisez une transaction DB.

    Votre enfin Les blocs sont toujours exécutés. Votre échantillon de code est correct - la méthode de niveau bas doit simplement avoir essayer et enfin . Par exemple, un appel non géré peut savoir qu'il doit disposer de la ressource non gérée, mais cela ne serait pas exposé à des méthodes .NET l'appelant. Cet appel devrait se débarrasser de la ressource non gétionnée dans son bloc enfin et appeler des méthodes gérées peut gérer des exceptions ou simplement les transmettre en hausse.

    S'il y a quelque chose dans une exception que vous Besoin de gérer Vous devez ré-jeter l'exception, par exemple: xxx


0 commentaires

5
votes

Ma devise est gérante ce que vous pouvez (ou avez besoin de) et laissez toutes les autres exceptions à la bulle et les attraper dans un événement non gré.

Vous êtes correct Tho, un bloc enfin est toujours appelé (même en cas d'exception étant soulevée dans la section Essayer) avant de quitter la méthode. Ainsi, que vous souhaitiez la prise de l'exception sur la méthode OUT ou non est entièrement à vous ..... Cela ne devrait pas affecter le bloc enfin appelé.


3 commentaires

Merci. Je suis d'accord en général avec l'idée "bulle". C'est à peu près ce que je fais à Java. Il y avait des raisons raisonnables d'attraper une exception (et de retirer certains) dans le cas où je cherchais.


Lancer des exceptions indigènes personnalisées?


Droite. Voir aussi Stackoverflow.com/Questtions/434839/...



11
votes

pour la question n ° 2: L'auteur signifiait "exceptions de l'état corrompu". Ils seront introduits dans .NET 4.0 (l'équipe CLR a annoncé cela à la PDC 2008 à Ce Talk ).

Les exceptions sur l'état corrompu ne peuvent être capturées par un bloc de capture normal. Exemples: violation d'accès, mémoire invalide.

mais vous pourrait vouloir attraper ces exceptions:

  1. dans Main () - Écrivez au journal, sortie, éteignez Addin
  2. De très rares cas lorsque vous savez que le code jette une exception comme celle-ci (par exemple, certains cas avec Interop avec code natif)

    Pour ce faire, vous devez mettre un attribut [GuineProcessCorruptedstateException] sur la méthode où vous souhaitez attraper CorrupteDstateException.

    Pour en savoir plus sur ces exceptions, veuillez consulter Cet article MSDN .


1 commentaires

Pas tout à fait la question que j'ai posée, mais une réponse très intéressante! Merci beaucoup.