Question

Parfois, je ne sais pas le type de sorcière d'exception dois-je jeter. Donc, je jette habituellement Exception (). Est-il un bel article à ce sujet?

Était-ce utile?

La solution

Si vous ne faites pas toute tentative de récupérer d'une erreur, vous pouvez simplement jeter un Exception avec une chaîne pour vous dire ce qui a mal tourné. (Ou si vous allez effectuer la même action quelle que soit erreur).

Autre que ce qui en fait évident pour un programmeur qui a mal tourné en utilisant un nouveau nom d'exception plutôt que de le mettre dans le message, et l'exception peut contenir des données pour vous aider à récupérer d'une exception particulière.

Par exemple, un ArgumentNullException a une ParamName de propriété, vous devez définir lorsque vous lancez l'exception. Lorsque les prises de l'appelant, il peut alors regarder cette propriété et décider de passer une nouvelle valeur pour l'argument qui a causé l'erreur, ou peut imprimer une erreur pertinente pour informer le programmeur qui a mal tourné.

Il est regrettable que les exceptions sont rarement utilisées à leur plein potentiel (dans de nombreuses API open source et autres), et sont souvent simplement inséré pour informer un programmeur qui a mal tourné. Il n'y a pas beaucoup de différence entre ces 2 si vous ne prévoyez pas de lire la propriété ParamName lorsque vous l'attrapez. (Beaucoup de gens ne dérangera pas, et seulement attraper un Exception de toute façon).

throw new ArgumentNullException("arg1");
throw new Exception("arg1 is null");

Il peut être difficile de récupérer d'une erreur complètement, mais dans certaines applications cependant, vous trouverez peut-être souhaitable de créer des exceptions personnalisées qui peuvent fournir tous les détails dont vous avez besoin.

Pour l'instant, je voudrais simplement mettre Exception dans la recherche du navigateur d'objets dans VS, et voir ce qui est déjà là. Leurs noms sont assez explicites, de sorte que vous devriez être en mesure de choisir quelque chose de convenable.

Autres conseils

Le problème de lancer une exception générique est qu'elle limite la capacité de votre code plus haut dans la pile pour gérer correctement (c.-à-meilleure pratique consiste à piéger la plus exception spécifique possible avant de retomber, et ne capture ce que vous pouvez poignée).

Jeffrey Richter a une excellente section sur la gestion des exceptions (y compris les informations sur l'espace de noms System.Exception) dans CLR via C #

"Framework Design Guidelines" par Cwalina et Abrahms couvre ce sujet vraiment bien (à mon humble avis).

Il est disponible gratuitement en ligne , ou le livre (pas libre) ici (Royaume-Uni) ou ici (Etats-Unis) . Regardez dans la section intitulée Lignes directrices de conception pour les exceptions .

Eh bien, la seule chose que vous ne devriez pas faire est de lancer Exception lui-même.
Cherchez toujours une sous-classe appropriée.

Je ne connais pas d'orthographe de la publication à laquelle exception à jeter quand, mais doit prendre soin ArgumentException et InvalidOperationException de la plupart de vos cas.

Poser des questions distinctes sur des cas séparés si elles se présentent.

Je suggère à diviser des exceptions en quelques catégories en fonction de l'état du système:

  1. La méthode a échoué de telle façon qu'il n'a rien fait; l'état de toutes les données sous-jacentes n'a pas été perturbé, et est probablement valable. scénarios typiques: essayer de récupérer d'une collection un objet qui est pas là, ou ajouter un qui est déjà. Un autre scénario possible: un délai d'attente de communication dans les cas où il ne devrait pas avoir causé une perte de données (et ont été Retrying l'opération pourrait réussir si le problème était tout simplement que l'autre extrémité était tout simplement trop lent).
  2. La méthode a échoué d'une manière qui peut avoir perturbé la structure de données sous-jacente ou la structure de données sous-jacentes peut avoir été corrompu précédemment. D'autres opérations ne doivent pas être tentées avec cette structure de données à moins que des mesures soient prises pour le valider. Un autre scénario possible: une communication time out apparaît lorsqu'un enregistrement a été partiellement récupéré et les données partiellement récupérées est perdu. Selon le protocole, il peut être nécessaire d'effectuer une action de récupération sur la connexion, ou pour le fermer et d'initier un nouveau.
  3. Quelque chose ne va pas avec l'état du système et la récupération est probablement pas possible.

Malheureusement, les exceptions existantes .net tout pour ne pas en forme comme ce modèle; il aurait été bien s'il y avait un type ExceptionBase dont les choses comme ThreadAbortException, CpuHasCaughtFireException, et l'exception « normale » ont été établies, et toutes les exceptions « normales » ont été tirées de l'exception. Je comprends que .net 4.0 bidouilles un peu dans une telle conception, mais je ne connais pas les mécanismes exacts. Dans tous les cas, je suggère que toutes les exceptions définies par l'utilisateur doivent être divisés en groupes comme ci-dessus, toutes les exceptions dans chaque groupe partageant un ancêtre commun distinct d'autres groupes.

Il y a un article de Krzysztof Cwalina ( "un architecte principal de l'équipe .NET Framework de Microsoft") appelé Choisir le bon type d'exception à Throw qui jette un peu de lumière à ce sujet. Il traite de choisir la bonne exception à jeter et des conseils sur la création d'exceptions personnalisées.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top