J'ai une méthode qui peut lever deux exceptions différentes, CommuncationException
et SystemException
. Dans les deux cas, je fais le même bloc de code à trois lignes.
try {
...
}
catch (CommunicationException ce) {
...
}
catch {SystemExcetion se) {
...
}
Y a-t-il une possibilité de le faire comme ça?
try {
...
}
catch (CommunicationException ce, SystemException se) {
...
}
Ensuite, je n'aurais pas à écrire autant de code. Je sais que je pourrais extraire la gestion des exceptions vers une méthode privée, mais comme le code ne fait que 3 lignes, la définition de la méthode prendrait plus de code que le corps lui-même.
En fait, vous ne pourriez attraper que SystemException
et il gérerait également CommunicationException
, car CommunicationException
est dérivé de SystemException
catch (SystemException se) {
... //this handles both exceptions
}
Si vous pouvez mettre à jour votre application en C # 6, vous avez de la chance. La nouvelle version C # a implémenté des filtres d'exception . Vous pouvez donc écrire ceci:
catch (Exception ex) when (ex is CommunicationException || ex is SystemException) {
//handle it
}
Certaines personnes pensent que ce code est le même que
catch (Exception ex) {
if (ex is CommunicationException || ex is SystemException) {
//handle it
}
throw;
}
Mais ce n'est pas. En fait, c'est la seule nouvelle fonctionnalité de C # 6 qui n'est pas possible d'émuler dans les versions précédentes. Tout d'abord, une relance signifie plus de frais généraux que de sauter le crochet. Deuxièmement, il n'est pas sémantiquement équivalent. La nouvelle fonctionnalité conserve la pile intacte lorsque vous déboguez votre code. Sans cette fonctionnalité, le vidage sur incident est moins utile, voire inutile.
Voir un discussion à ce sujet sur CodePlex . Et un exemple montrant la différence .
Malheureusement, il n'y a aucun moyen. La syntaxe que vous avez utilisée n'est pas valide et une chute comme dans une instruction switch n'est pas possible non plus. Je pense que vous devez utiliser la méthode privée.
Une petite solution de rechange hacky serait quelque chose comme ceci:
var exceptionHandler = new Action<Exception>(e => { /* your three lines */ });
try
{
// code that throws
}
catch(CommuncationException ex)
{
exceptionHandler(ex);
}
catch(SystemException ex)
{
exceptionHandler(ex);
}
Vous devez décider par vous-même si cela a un sens.
Non, vous ne pouvez pas le faire de cette façon. La seule façon que je sache est d'attraper une exception générique, puis de vérifier de quel type il s'agit:
try
{
...
}
catch(Exception ex)
{
if(ex is CommunicationException || ex is SystemException)
{
...
}
else
{
... // throw; if you don't want to handle it
}
}
Qu'en est-il de
try {
...
}
catch (CommunicationException ce) {
HandleMyError(ce);
}
catch {SystemExcetion se) {
HandleMyError(se);
}
private void HandleMyError(Exception ex)
{
// handle your error
}
Duplicata possible de
Attraper plusieurs exceptions à la fois?
Je cite la réponse ici:
catch (Exception ex)
{
if (ex is FormatException ||
ex is OverflowException)
{
WebId = Guid.Empty;
return;
}
else
{
throw;
}
}
Puisque vous faites de même pour les deux types d'exceptions, vous pouvez simplement aller:
try
{
//do stuff
}
catch(Exception ex)
{
//normal exception handling here
}
N'attrapez des types d'exception explicites que si vous devez faire quelque chose d'unique pour cela.