Comme vous le savez tous probablement, attraper et re-jeter une exception en C # de cette façon est diabolique, car il détruit la trace de la pile: la bonne façon de réapprocher Exception sans perdre la trace de la pile est ceci: p> Le seul problème est que je reçois beaucoup d'avertissements de compilation: "La variable 'ex' est déclarée mais jamais utilisée ". Si vous en avez beaucoup, un avertissement utile peut être caché dans les ordures. Donc, c'est ce que j'ai fait: p> try
{
if(dummy)
throw new DummyException();
}
catch (DummyException)
{
throw;
}
catch(AnotherException ex)
{
//handle it
}
6 Réponses :
Si vous ne faites rien avec DummyException code> dans le bloc CODE> CATCH CODE> Bloc (que vous ne pouvez pas, car vous ne l'avez pas donné un identifiant), pourquoi pas Débarrassez-vous du
essayer / attraper code> bloc entièrement? Par exemple, faites cela:
throw new DummyException();
La raison pour laquelle vous pourrez attraper DummyException code> spécifiquement et simplement le jeter est que vous pourriez le gérer à un niveau plus élevé (plus proche du UI). Et
try / attrape code> vous permet à A) incluent un
enfin code> si vous en avez besoin d'un, et B) pour attraper plusieurs exceptions.
@Alleng Il est correct d'avoir un essayer / enfin code> qui n'a pas de
attrape code> blocs. Je ne sais pas avec certitude, mais je ne serais pas surpris si le compilateur a optimisé sa prise.
@Mattgree: True: Mais vous avez toujours besoin du essayer code>. Je faisais référence à la suggestion de "se débarrasser du
try / attraper code> bloc entièrement" que vous ne voudriez pas faire - puisque vous avez au moins besoin du
essayer code> .
@Alleng Bon points à prendre en compte; Ma réponse a été basée sur l'exemple de l'OP (aucun autre Catch code> blocs et non
enfin code>).
@Donut, j'ai donné cet exemple parce que cela montre mon problème - n'utilise pas la variable si je vais à ressusion, ce qui me donne un avertissement de compilateur. Dans un code réel, j'aurais plusieurs captures et / ou un blocage enfin
@Andre assez équitable, bien que je dirais que le passage de l'exception non confondu de la pile a quelques inconvénients (c'est-à-dire créer plusieurs points de sortie de la fonction).
Il n'y a pas d'inconvénient à cela. Vous dites simplement au compilateur "Je prévois d'attraper cette exception, mais je n'ai pas besoin d'une référence à l'exception réelle", cela n'affecte pas la manière dont les choses sont lancées ou la façon dont les exceptions fonctionnent. Votre dernier exemple est le moyen idéal de faire ce que vous voulez, cependant, si vous allez simplement aller immédiatement à lancer; code> avec rien d'autre dans le bloc, alors pourquoi attraper le tout? P>
Pourquoi attraper si vous allez simplement rejeter? Quoi qu'il en soit, vous voudrez peut-être jeter un coup d'œil à cette discussion précédente. Bien que non identique une grande partie de ce qui est discuté est pertinent: p>
Merci pour le lien. Répondre à votre question, le code n'est qu'un exemple, je peux re-jeter un type d'exception mais pas d'autres (si vous avez plusieurs blocs de capture)
lance réellement une exception en utilisant "lancer;" strong> est un .NET Meilleure pratique forte>, car il préserve la trace de la pile d'exception. P>
Lancer des exceptions en utilisant "Three Ex;" strong> est considéré comme strong> une pire pratique forte>, car elle perd la trace d'originale de la pile et doit être évitée. P>
Il affirme réellement que dans la question ... :)
J'aimerais savoir s'il y a un inconvénient de ré-jeter une exception qui n'est pas définie sur une variable. P> blockQuote>
Non, il n'y a pas de pas du tout. Une variable n'est nécessaire que si vous souhaitez faire référence à l'exception dans votre code, mais que vous n'avez pas besoin de le faire avec une instruction code> code>, vous n'avez pas besoin d'une variable du tout. p>
Et vous avez exactement la bonne idée en essayant d'éliminer les avertissements du compilateur «bruyant». Ils ont tendance à enterrer des erreurs importantes que vous les em> voulez-vous corriger et d'obtenir une construction propre est toujours importante. La meilleure solution consiste simplement à réécrire le code pour utiliser un paramètre
Catch code>. P>
Cependant, soyez conscient que dans 82% des cas que je vois * sup>, c'est une erreur d'écrire du code qui utilise
lancer code> du tout. Vous ne devriez généralement pas attraper des exceptions que vous ne savez pas comment gérer et votre seule stratégie «de manutention» prévue est de repousser. Il y a des cas où, même en utilisant
lancer code>, peut réinitialiser la pile d'appels, ce qui vous oblige à perdre d'importantes informations de débogage. Il existe également de meilleures alternatives pour la journalisation des exceptions à attraper / retirent. Vous pouvez trouver plus d'informations dans les réponses à ces questions: P>
- code de méthode principal entièrement à l'intérieur TRY / Capture: est-ce une mauvaise pratique? li>
- quoi Peut mener un lancer pour réinitialiser une piqystack (j'utilise "lancer", pas "Thoe ex") li> ul>
Il n'y a absolument rien de mal à laisser des exceptions à la bulle et à les manipuler tous dans un endroit central. La règle à garder à l'esprit est que vous ne devriez pas utiliser des exceptions pour le contrôle des flux. Mais il n'y a rien de mal à jeter une exception dans le code de niveau bas et à montrer à l'utilisateur un message d'erreur supérieur à la pile dans le code de l'interface utilisateur. Lisez Microsoft's Meilleures pratiques pour la gestion des exceptions pour certains conseils généraux. p>
* sup> légèrement plus que Le pourcentage de statistiques composées sur place . SUB> P>
Merci pour votre réponse, c'est exactement ce que je cherchais. J'ai déjà fait beaucoup d'erreurs dans la manipulation des exceptions, mais je pense que je suis un peu mieux avec ça maintenant. Je les manipulez généralement à l'intérieur de la méthode ou d'une couche en évitant que cela va trop de couches. Je jette habituellement une exception décochée qui bulle et donne un message d'erreur générique à l'utilisateur. Est-ce une mauvaise pratique?
@andre: Il n'y a absolument rien de mal à laisser des exceptions à la bulle et à les manipuler tous dans un endroit central. La règle à garder à l'esprit est que vous ne devriez pas utiliser des exceptions pour le contrôle des flux. Mais il n'y a rien de mal à jeter une exception dans le code de niveau bas et à montrer à l'utilisateur un message d'erreur supérieur à la pile dans le code de l'interface utilisateur. Vous devrez probablement poster un réel échantillon de code pour que je soit plus spécifique. Mais vous devriez lire Microsoft's Meilleures pratiques pour la manipulation d'exceptions pour quelques conseils généraux .
Pourquoi attraper et retirh comme ça? Pourquoi les gens doivent-ils toujours supposer qu'ils savent chaque cas? Réponse: transactions de base de données.
Si vous avez une meilleure façon de le faire, veuillez parler du Dr Proton, aucune infraction prise. Gardez à l'esprit qu'il existe de nombreux systèmes de base de données différents utilisés, mais la plupart d'entre eux supportent le contrôle des transactions (commencements / commit / Rollback) et ont des interfaces C #. P>
pseudocode (cas simplifié): P): P >
try { db.beginTrans(); db.doStuff(); db.doOtherStuff(); db.commitTrans(); } catch { db.rollbackTrans(); throw; }
Voici un message que j'ai trouvé qui offre une idée et une solution possible: weblogs.asp.net/fmarguerie/archive/2008/01/02/...
ERM, pourquoi dans le monde jetez-vous une exception, attrapez-le et retirez-le Tout de la même méthode B>?
@Cody Grey - Je devine juste, ici, mais (donnant au profit du doute) Je suppose qu'il vient de fournir un exemple de code pour montrer qu'il comprend la différence entre
lancer code> et
et
lancer ex code>. Non pas qu'il générait réellement une exception dans une méthode qui attrape cette exception, puis le retire. J'espère quand même.
@Cody Grey, @alleng a raison, c'est juste un exemple simple pour montrer ce que j'essaie d'atteindre, pas un vrai code
D'accord, bien. C'est ce que j'espérais, et pourquoi j'ai posté cela comme un commentaire plutôt qu'une réponse. Vous seriez surpris du genre de folie que je vois les gens à faire ici avec des exceptions / attraper.