web-dev-qa-db-fra.com

Gestion des exceptions plus élégante que plusieurs blocs de capture?

En utilisant C #, existe-t-il un meilleur moyen de gérer plusieurs types d'exceptions plutôt qu'un tas de blocs de capture laids?

Quelle est la meilleure pratique pour ce type de situation?

Par exemple:

try
{
    // Many types of exceptions can be thrown
}
catch (CustomException ce)
{
    ...
}
catch (AnotherCustomException ace)
{
    ...
}
catch (Exception ex)
{
    ...
}
45
Aaron

À mon avis, un tas de blocs de capture "laids" IS la meilleure façon de gérer cette situation.

La raison pour laquelle je préfère cela est qu'elle est très explicite. Vous indiquez explicitement quelles exceptions vous souhaitez gérer et comment elles doivent être gérées. D'autres formes de fusion de la manipulation dans des formes plus concises perdent en lisibilité dans la plupart des cas.

Mon conseil serait de s'en tenir à cela, et de gérer les exceptions que vous souhaitez gérer explicitement, chacune dans son propre bloc catch.

70
Reed Copsey

Je suis d'accord avec Reed: c'est la meilleure approche.

J'ajouterais ces commentaires:

N'attrapez que quelque chose sur lequel vous allez faire quelque chose. Si vous ne pouvez pas résoudre le problème, il est inutile d'attraper une exception spécifique.

N'exagérez pas l'utilisation des blocs de capture. Dans de nombreux cas où vous ne pouvez pas résoudre l'exception, il est préférable de laisser l'exception bouillonner jusqu'à un point central (tel que▶Error) et de l'attraper là. Ensuite, vous enregistrez l'exception et affichez un message à l'utilisateur.

21
DOK

La seule autre chose que vous pouvez faire est d'émuler les filtres d'exception de VB.NET:

try {
    DoSomething();
} catch (Exception e) {
    if (!ex is CustomException && !ex is AnotherCustomException) {
       throw;
    }
    // handle
}

Parfois, c'est mieux, parfois non. Je l'utiliserais principalement s'il y avait une logique commune que je voulais dans le gestionnaire, mais les exceptions ne partagent pas un type de base.

15
Mark Brackett

Malheureusement, C # n'a pas de filtres d'exception utilisateur comme VB.NET, vous êtes donc limité à:

  1. Attraper un ancêtre commun à toutes les exceptions. Cela peut ou non être ce que vous voulez, car il peut y avoir d'autres types d'exception descendants que vous ne souhaitez pas intercepter.
  2. Déplacer la logique de gestion des exceptions dans une autre méthode et l'appeler à partir de chaque gestionnaire.
  3. Répétition de la logique d'exception pour chaque gestionnaire.
  4. Déplacement de la logique de gestion des exceptions dans un langage prenant en charge les filtres, tel que VB.NET.
10
Kent Boogaart

Si vous avez besoin d'écrire une très grande quantité de code comme celle-ci, je vous suggère de vérifier un cadre AOP . J'utilise personnellement PostSharp . Ensuite, vous pouvez masquer tout le code de gestion des exceptions dans des aspects.

5
user94636

Vous devriez vérifier la bibliothèque d'entreprise bloc de gestion des exceptions . Il permet un contrôle beaucoup plus fin du grain sur les exceptions via des politiques (politiques d'encapsulation, politiques de propagation, politiques de remplacement, politiques de journalisation, etc.) Vous pouvez l'utiliser pour normaliser la façon dont vous codez un bloc d'exception et utilisez la configuration pour gérer précisément ce qui se passe avec un type particulier d'exception.

2
JP Alioto

N'est-ce pas bien ainsi?

Si vous souhaitez gérer une seule exception:

try
{
    // Many types of exceptions can be thrown
}
catch (TheExceptionIWantToHandle ex)
{
    // handle it
}
catch (Exception ex)
{
    // suppress all other exceptions
}

Si vous souhaitez gérer toutes les exceptions sauf une:

try
{
    // Many types of exceptions can be thrown
}
catch (TheExceptionIDoNotWantToHandle ex)
{
    // suppress all other exceptions
}
catch (Exception ex)
{
    // handle it
}

bon, pas bon?

0
stanleyxu2005