Il y a quelques articles qui demandent quelle est déjà la différence entre ces deux.
(pourquoi dois-je même mentionner cela ...)
Mais ma question est différente dans un sens que j'appelle "throw ex" dans une autre méthode de manipulation de type erreur .
public class Program {
public static void Main(string[] args) {
try {
// something
} catch (Exception ex) {
HandleException(ex);
}
}
private static void HandleException(Exception ex) {
if (ex is ThreadAbortException) {
// ignore then,
return;
}
if (ex is ArgumentOutOfRangeException) {
// Log then,
throw ex;
}
if (ex is InvalidOperationException) {
// Show message then,
throw ex;
}
// and so on.
}
}
Si elles try & catch
étaient utilisées dans le Main
, alors j'utiliserais throw;
pour renvoyer l'erreur. Mais dans le code simplifié ci-dessus, toutes les exceptions passent parHandleException
A throw ex;
le même effet que d'appeler throw
lorsqu'il est appelé à l'intérieur HandleException
?
c#
.net
exception
exception-handling
dance2die
la source
la source
Réponses:
Oui, il y a une différence;
throw ex
réinitialise la trace de la pile (de sorte que vos erreurs semblent provenirHandleException
)throw
ne le fait pas - le délinquant d'origine serait conservé.la source
(J'ai posté plus tôt, et @Marc Gravell m'a corrigé)
Voici une démonstration de la différence:
et voici la sortie:
Vous pouvez voir que dans l'exception 1, la trace de la pile revient à la
DivByZero()
méthode, alors que dans l'exception 2, ce n'est pas le cas.Notez cependant que le numéro de ligne indiqué dans
ThrowException1()
etThrowException2()
est le numéro de ligne de l'throw
instruction, pas le numéro de ligne de l'appel àDivByZero()
, ce qui est probablement logique maintenant que j'y pense un peu ...Sortie en mode Release
Exception 1:
Exception 2:
Est-ce qu'il maintient le stackTrace original en mode débogage uniquement?
la source
DevideByZero
, donc la trace de pile EST la même. vous devriez peut-être poster ceci comme une question de son propre chefLes autres réponses sont entièrement correctes, mais cette réponse fournit des détails supplémentaires, je pense.
Considérez cet exemple:
Si vous décommentez la
throw arithExc;
ligne, votre sortie est:Vous avez certainement perdu des informations sur le lieu de cette exception. Si vous utilisez plutôt la
throw;
ligne, voici ce que vous obtenez:C'est beaucoup mieux, car maintenant vous voyez que c'est la
Program.Div
méthode qui vous a posé problème. Mais il est toujours difficile de voir si ce problème vient de la ligne 35 ou de la ligne 37 dutry
bloc.Si vous utilisez la troisième alternative, encapsulant dans une exception externe, vous ne perdez aucune information:
En particulier, vous pouvez voir que c'est la ligne 35 qui pose problème. Cependant, cela nécessite que les gens recherchent le
InnerException
, et il semble quelque peu indirect d'utiliser des exceptions internes dans des cas simples.Dans ce billet de blog, ils conservent le numéro de ligne (ligne du bloc try) en appelant (par réflexion) la
internal
méthode intanceInternalPreserveStackTrace()
sur l'Exception
objet. Mais ce n'est pas agréable d'utiliser une réflexion comme celle-ci (le .NET Framework pourrait changer leursinternal
membres un jour sans avertissement).la source
comprenons la différence entre lancer et lancer ex. J'ai entendu dire que dans de nombreuses interviews .net, cette question courante était posée.
Juste pour donner un aperçu de ces deux termes, throw et throw ex sont tous deux utilisés pour comprendre où l'exception s'est produite. Throw ex réécrit la trace d'exception de la pile quel que soit l'endroit où elle a été levée.
Comprenons avec un exemple.
Comprenons d'abord Throw.
la sortie de ce qui précède est ci-dessous.
montre la hiérarchie complète et le nom de la méthode où l'exception a été levée. C'est M2 -> M2. avec les numéros de ligne
Deuxièmement .. permet de comprendre par jet ex. Remplacez simplement throw par throw ex dans le bloc catch de la méthode M2. comme ci-dessous.
la sortie du code throw ex est comme ci-dessous.
Vous pouvez voir la différence dans la sortie. Throw ex ignore simplement toute la hiérarchie précédente et réinitialise la trace de la pile avec la ligne / méthode où throw ex est écrit.
la source
Lorsque vous le faites
throw ex
, cette exception levée devient celle "d'origine". Ainsi, toute trace de pile précédente ne sera pas là.Si vous le faites
throw
, l'exception va juste au bout de la ligne et vous obtiendrez la trace complète de la pile.la source
Non, cela entraînera l'exception pour avoir une trace de pile différente. Seule l'utilisation d'un
throw
objet sans exception dans lecatch
gestionnaire laissera la trace de pile inchangée.Vous souhaiterez peut-être renvoyer un booléen à partir de HandleException, que l'exception soit renvoyée ou non.
la source
MSDN signifie :
la source
Regardez ici: http://blog-mstechnology.blogspot.de/2010/06/throw-vs-throw-ex.html
Lancer :
Il conserve les informations de la pile avec exception
Cela s'appelle "Rethrow"
Si vous voulez lever une nouvelle exception,
Lancer Ex :
Il n'enverra pas d'informations sur la pile avec exception
Cela s'appelle "Briser la pile"
Si vous voulez lever une nouvelle exception,
la source
Pour vous donner une perspective différente à ce sujet, l'utilisation de throw est particulièrement utile si vous fournissez une API à un client et que vous souhaitez fournir des informations de trace de pile détaillées pour votre bibliothèque interne. En utilisant throw ici, j'obtiendrais la trace de la pile dans ce cas de la bibliothèque System.IO.File pour File.Delete. Si j'utilise throw ex, ces informations ne seront pas transmises à mon gestionnaire.
la source
si toutes les lignes 1, 2 et 3 sont commentées - Sortie - ex interne
si toutes les lignes 2 et 3 sont commentées - Sortie - ex interne System.DevideByZeroException: {"Tentative de division par zéro."} ---------
si toutes les lignes 1 et 2 sont commentées - Sortie - ex interne System.Exception: diviser par 0 ----
si toutes les lignes 1 et 3 sont commentées - Sortie - ex interne System.DevideByZeroException: {"Tentative de division par zéro."} ---------
et StackTrace sera réinitialisé en cas de lancer ex;
la source