Lors de la levée d'une exception?
J'ai exceptions créées pour chaque condition que ma demande ne se fait pas attendre. UserNameNotValidException
, PasswordNotCorrectException
etc.
Cependant, j'ai été dit que je ne devrait pas créer des exceptions à ces conditions. Dans mon UML ceux qui SONT des exceptions à l'écoulement principal, alors pourquoi ne devrait-elle pas être une exception?
Toute orientation ou de meilleures pratiques pour la création d'exceptions?
- Veuillez rouvrir, c'est un très raisonnable et une question valable. Toute question implique une certaine quantité de l'opinion, mais dans ce cas, je soupçonne que c'est une question de "meilleures pratiques".
- +1 pour les rouvrir. Comme de nombreux autres sujets intéressants "ça dépend" et il est très utile pour analyser les avantages et les inconvénients lors de la prise de décisions. Le fait que les gens confondent opinions sur des faits dans les réponses ne nie pas cela. Passant au crible de la boue est un exercice qui doit être laissée au lecteur.
- Je suis également d'avis que cette question devrait être rouverte comme il est lié à de meilleures pratiques. Par la façon dont les pratiques exemplaires sont toujours des opinions qui peuvent aider les autres.
- Microsoft a dit: "Ne retournez pas les codes d'erreur. Les Exceptions sont le principal moyen d'erreurs de déclaration dans les cadres." et "...Si un membre ne peut pas réussir à faire ce qu'il est conçu pour faire, cela devrait être considéré comme un échec de l'exécution et qu'une exception doit être levée.". msdn.microsoft.com/library/ms229030%28v=vs.100%29.aspx
- Ces peut être totalement raisonnable exception, ça dépend des méthodes qui les lance. Une méthode appelée
IsCredentialsValid(username,password)
ne devrait pas lever une exception si le nom d'utilisateur ou mot de passe n'est pas valide, mais retourne la valeur false. Mais dire une méthode qui lit les données à partir de la base de données pourrait légitimement lancer une exception, si l'authentification échoue. En bref: Vous devez lever une exception si une méthode n'est pas capable de faire le travail qu'il est censé faire. - Généralement, les exceptions doivent être utilisés que si la fonction que l'avis de l'erreur ne peut pas récupérer à partir de ce.
Vous devez vous connecter pour publier un commentaire.
Mon orientation est: une exception est levée lors d'une hypothèse fondamentale de l'actuel bloc de code est fausse.
Exemple 1: dire que j'ai une fonction qui est censé examiner arbitraire de la classe et retourne true si cette classe hérite de la Liste<>. Cette fonction pose la question, "cet objet Est-il un descendant de la Liste?" Cette fonction ne doit jamais lever une exception, car il n'existe pas de zones grises, dans son fonctionnement, chaque classe ou de ne pas hériter de la Liste<>, donc la réponse est toujours "oui" ou "non".
Exemple 2: dire que j'ai une autre fonction qui examine une Liste<>, et retourne true si sa longueur est de plus de 50, et false si la longueur est de moins en moins. Cette fonction pose la question, "est-ce que cette liste ont plus de 50 articles?" Mais cette question fait une hypothèse, il suppose que l'objet auquel il est donné une liste. Si j'ai la main un NUL, alors que l'hypothèse est fausse. Dans ce cas, si la fonction renvoie soit true ou false, c'est la rupture de ses propres règles. La fonction ne peut pas retourner tout et de prétendre qu'il a répondu correctement à la question. Donc, il n'est pas de retour, il lève une exception.
Ceci est comparable à la "question piège" erreur de logique. Chaque fonction pose une question. Si l'entrée est donné fait de cette question une erreur, puis lancer une exception. Cette ligne est plus difficile que de dessiner avec des fonctions qui retourne void, mais la ligne de fond est la suivante: si la fonction d'hypothèses sur ses entrées sont violés, il doit lever une exception, au lieu de retourner normalement.
L'autre côté de cette équation est: si vous trouvez que vos fonctions de lever des exceptions fréquemment, alors vous avez probablement besoin d'affiner leurs hypothèses.
Parce qu'ils sont des choses qui vont se produire normalement. Les Exceptions ne sont pas de contrôle de flux de mécanismes. Souvent, les utilisateurs d'obtenir les mots de passe mal, ce n'est pas un cas exceptionnel. Les Exceptions doivent être vraiment une chose rare,
UserHasDiedAtKeyboard
type de situations.logUserIn
et l'utilisateur reçoit un mot de passe incorrect 5 fois dans une rangée, il doit lever une exception, et l'appelant de faire face avec l'attaquant potentiel. Sauf si la fonction est en faitlogUserInAndThrottleForPotentialAttacks
. Mais quelle merde, non cohérent fonction. Comment les "mauvais" d'une condition est inversement proportionnelle à la quantité de fonction est responsable.Mon petit directives sont fortement influencés par le grand livre "Code complete":
Il n'est PAS une exception, si le nom d'utilisateur n'est pas valide ou le mot de passe n'est pas correct. Ce sont des choses que vous devriez vous attendre dans le flux normal de fonctionnement. Les Exceptions sont des choses qui ne font pas partie du programme normal de l'opération et sont assez rares.
EDIT: je n'aime pas utiliser des exceptions, car vous ne pouvez pas dire si une méthode lève une exception juste en regardant à l'appel. C'est pourquoi les exceptions ne devraient être utilisés que si vous ne pouvez pas gérer la situation d'une manière décente (penser "out of memory" ou "ordinateur est sur le feu").
Une règle de base est d'utiliser des exceptions dans le cas de quelque chose que vous ne pourriez normalement pas prédire. Des exemples sont connectivité de base de données, fichier manquant sur le disque, etc. Pour les scénarios que vous pouvez prédire, c'est à dire les utilisateurs essayant de se connecter avec un mot de passe incorrect, vous devriez être en utilisant les fonctions qui retournent des valeurs booléennes et de savoir comment gérer la situation correctement. Vous ne voulez pas brusquement fin de l'exécution par la levée d'une exception juste parce que quelqu'un fait une faute de frappe leur mot de passe.
D'autres proposent que les exceptions ne doivent pas être utilisées à cause de la mauvaise connexion est à prévoir dans un flux normal si l'utilisateur mistypes. Je suis en désaccord et je ne comprends pas le raisonnement. Comparer avec l'ouverture d'un fichier.. si le fichier n'existe pas ou n'est pas disponible pour quelque raison que ce soit, une exception sera levée par le cadre. À l'aide de la logique ci-dessus, ce fut une erreur de la part de Microsoft. Ils devraient avoir renvoyé un code d'erreur. Même pour l'analyse, la webrequests, etc., etc..
Je ne considère pas un mauvais login partie d'un flux normal, c'est exceptionnel. Normalement, l'utilisateur tape le mot de passe correct, et le fichier n'existe pas. Les cas exceptionnels sont exceptionnels et c'est très bien d'utiliser les exceptions pour les personnes. Compliquer votre code, en propageant les valeurs de retour par le biais de n niveaux de la pile est un gaspillage d'énergie et en conséquence dans le code désordre. Faire la chose la plus simple qui pourrait éventuellement fonctionner. Ne pas prématurément optimiser en utilisant les codes d'erreur, exceptionnelle des trucs, par définition, est rarement le cas, et les exceptions ne coûtent rien, sauf si vous les jeter.
login
-type de méthode serait qu'un mot de passe est incorrect, il peut être utilisé pour déterminer cela, et ne voudrais pas avoir une exception à cette affaire; considérant que, dans unfile open
type de scénario, ce qui a un résultat souhaité - si le système est dans l'impossibilité de livrer le résultat dus à une erreur de paramètres d'entrée ou un facteur externe, qui est parfaitement logique d'utilisation d'une exception.Exceptions sont un peu coûteux effet, si par exemple vous avez un utilisateur qui fournit un mot de passe invalide, il est généralement une meilleure idée de passer de nouveau un échec drapeau, ou tout autre indicateur qu'il est invalide.
Cela est dû à la façon dont les exceptions sont gérées, véritable mauvaise entrée, et unique arrêt critique les articles doivent être des exceptions, mais pas de connexion a échoué info.
Je pense que vous ne devriez jeter une exception quand il n'y a rien que vous pouvez faire pour sortir de votre état actuel. Par exemple, si vous allouez de la mémoire et il n'est pas tout à allouer. Dans le cas que vous citez, vous pouvez le récupérer à partir de ces états, il peut retourner un code d'erreur de retour à votre appelant en conséquence.
Vous verrez beaucoup de conseils, y compris dans les réponses à cette question, que vous devriez jeter des exceptions uniquement dans des circonstances "exceptionnelles". Qui semble à première vue raisonnable, mais est erronée, des conseils, car il remplace une question ("quand dois-je lancer une exception") avec un autre subjective de la question ("ce qui est exceptionnel"). Au lieu de cela, suivez les conseils de Herb Sutter (pour le C++, disponible dans le Dr Dobbs article Quand et Comment Utiliser les Exceptions, et aussi dans son livre avec Andrei Alexandrescu, C++ Normes de Codage): lever une exception si, et seulement si
impossible) ou
Pourquoi est-ce mieux? N'est-il pas de remplacer la question avec plusieurs des questions sur les préconditions, postconditions et invariants? C'est mieux pour plusieurs raisons.
throw
est un détail d'implémentation. Il nous oblige à garder à l'esprit que nous devons envisager la conception et de sa mise en œuvre séparément, et notre travail en mettant en œuvre une méthode est de produire quelque chose qui satisfait les contraintes de conception.catch
clauses.Je dirais il n'y a pas de règles strictes sur l'utilisation des exceptions. Cependant, il existe de bonnes raisons pour utiliser ou de ne pas les utiliser:
Raisons de l'utilisation d'exceptions:
Raisons de ne pas utiliser les exceptions:
En général, je serais plus enclin à utiliser les exceptions en Java qu'en C++ ou C#, parce que je suis de l'avis qu'une exception, déclarée ou non, est fondamentalement partie de l'interface formelle d'une fonction, puisque la modification de votre exception de garantie peut casser le code appelant. Le plus grand avantage de les utiliser en Java de l'OMI, c'est que vous savez que votre interlocuteur DOIT gérer l'exception, et cela améliore les chances de corriger son comportement.
De ce fait, dans n'importe quelle langue, je serais toujours tirer toutes les exceptions dans une couche de code ou de l'API à partir d'une même classe, de sorte que le code appelant peut toujours garantir à attraper toutes les exceptions. Aussi je pense qu'il serait mauvais pour jeter l'exception des classes qui sont spécifiques à l'implémentation, lors de l'écriture d'une API ou d'une bibliothèque (c'est à dire envelopper les exceptions de la baisse des couches de sorte que l'exception que votre interlocuteur reçoit est compréhensible dans le contexte de votre interface).
Noter que Java fait la distinction entre le général et l'Exécution des exceptions en ce que ce dernier n'a pas besoin d'être déclarée. Je tiens seulement à l'utilisation d'Exécution des classes d'exception lorsque l'on sait que l'erreur est le résultat d'un bug dans le programme.
Classes d'Exception sont comme "normal" des classes. Vous créez une nouvelle classe quand il "est" un type d'objet différent, avec différents domaines et différentes opérations.
En règle générale, vous devriez essayer de l'équilibre entre le nombre d'exceptions et de la granularité des exceptions. Si votre méthode lève plus de 4-5 différentes exceptions, vous pouvez probablement fusionner certains d'entre eux en plus "générale" des exceptions (par exemple dans votre cas "AuthenticationFailedException"), et en utilisant le message de l'exception à détail ce qui s'est passé. À moins que votre code poignées de chacun d'eux différemment, vous n'avez pas besoin de crée de nombreuses classes d'exception. Et si elle ne peut vous devriez juste de retour d'un enum avec l'erreur qui s'est produit. C'est un peu plus propre de cette façon.
Si c'est le code s'exécute à l'intérieur d'une boucle qui entraînera probablement une exception, encore et encore, puis de lever des exceptions n'est pas une bonne chose, car ils sont assez lents pour les grandes N. Mais il n'y a rien de mal à jeter personnalisé des exceptions si la performance n'est pas un problème. Assurez-vous juste que vous avez une base d'exception qu'ils ont tous inherite, appelé BaseException ou quelque chose comme ça. BaseException hérite du Système.Exception, mais l'ensemble de vos exceptions héritent BaseException. Vous pouvez même avoir un arbre d'Exception types de groupe de types similaires, mais cela peut ou peut ne pas être exagéré.
Donc, la réponse courte est que si cela ne cause pas de perte de performances significatives (ce qui ne devrait pas, sauf si vous êtes lancer beaucoup d'exceptions), puis aller de l'avant.
int.MaxValue
temps et de générer des "division par zéro" exception en elle. Le SI/d'AUTRE version, dans lequel j'ai été vérifier si le dividende n'est pas zéro avant l'opération de division, achevé en 6082 ms et 15407722 tiques alors que le TRY/CATCH version, dans lequel j'ai été génératrice de l'exception et de la capture de l'exception, achevé en 28174385 ms et 71371326155 tiques: un énorme 4632 fois plus que le si/d'autre version.Je suis d'accord avec japollock là-haut--jeter une acception lorsque vous avez un doute sur le résultat d'une opération. Les appels à l'Api, l'accès à des systèmes de fichiers, base de données des appels, etc. N'importe quand vous êtes en déplacement depuis les "limites" de votre langages de programmation.
Je tiens à ajouter, n'hésitez pas à jeter une exception. Sauf si vous allez faire quelque chose de "différent" (ignorer, e-mail, journal, montrent que twitter baleine image bidule, etc), alors ne vous embêtez pas avec la coutume des exceptions.
la règle de base pour lancer des exceptions est assez simple. vous le faites lorsque votre code est entré dans une IRRÉMÉDIABLE état non VALIDE. si des données est compromise ou que vous ne pouvez pas revenir en arrière le traitement qui en sont produites jusqu'à ce point, alors vous devez y mettre fin. en effet, quoi d'autre pouvez-vous faire? votre logique de traitement finira par échouer ailleurs. si vous pouvez le récupérer en quelque sorte, puis faire et ne pas jeter l'exception.
dans votre cas particulier, si vous avez été forcé de faire quelque chose de stupide comme accepter le retrait d'argent et seulement ensuite, vérifiez d'utilisateur/mot de passe, il faut arrêter le processus en levant une exception pour avertir que quelque chose de mauvais s'est passé et prévenir d'autres dommages.
En général, vous souhaitez lancer une exception pour tout ce qui peut arriver dans votre application qui est "Exceptionnel"
Dans votre exemple, deux de ces exceptions ressembler à vous de les appeler via un mot de passe /nom d'utilisateur de validation. Dans ce cas, il peut être soutenu que ce n'est pas vraiment exceptionnel que quelqu'un aurait une erreur de saisie d'un nom d'utilisateur /mot de passe.
Ils sont des "exceptions" au flux principal de votre UML, mais sont plus "branches" dans le traitement.
Si vous avez tenté d'accéder à votre fichier de mots de passe ou les données de base et ne pouvait pas, ce serait un cas exceptionnel et justifie la levée d'une exception.
Tout d'abord, si les utilisateurs de votre API ne sont pas intéressés en particulier, à grain fin échecs, puis d'avoir des exceptions spécifiques pour eux n'est d'aucune valeur.
Car il est souvent impossible de savoir ce qui peut être utile pour vos utilisateurs, une meilleure approche est d'avoir les exceptions spécifiques, mais de s'assurer qu'ils héritent d'une classe commune (par exemple, std::exception ou de ses dérivés en C++). Qui permet à votre client pour attraper les exceptions spécifiques s'ils le souhaitent, ou plus générale, à l'exception si elles n'avez pas de soins.
Exceptions sont destinés à des événements qui sont des comportements anormaux, des erreurs, des échecs, et ces. Comportement fonctionnel, erreur de l'utilisateur, etc., devraient être traitées par la logique du programme à la place. Depuis un mauvais compte ou mot de passe est une partie de la logique de flux dans une connexion de routine, il doit être capable de gérer ces situations sans exceptions.
J'ai des problèmes philosophiques avec l'utilisation d'exceptions. Fondamentalement, vous vous attendez à un scénario spécifique, mais plutôt que de le manipuler explicitement vous appuyez sur le problème de congé pour être manipulés "ailleurs". Et où cet "ailleurs", c'est peut être n'importe qui conjecture.
Je dirais que généralement tous fondamentalisme mène à l'enfer.
Vous certainement ne voulez pas finir à l'exception débit, mais en évitant les exceptions, est également une mauvaise idée. Vous devez trouver un équilibre entre les deux approches. Ce que je ne voudrais pas faire est de créer un type d'exception pour tous les situation exceptionnelle. Qui n'est pas productif.
Ce que je préfère en général est de créer deux types d'exceptions qui sont utilisés dans l'ensemble du système: LogicalException et TechnicalException. Ceux-ci peuvent être distingués par des sous-types, si nécessaire, mais il n'est généralement pas nécessaire.
La technique exception désigne le vraiment inattendu exception comme serveur de base de données vers le bas, la connexion au service web a jeté le IOException et ainsi de suite.
D'autre part, la logique des exceptions sont utilisés pour propager les moins graves erronée de la situation dans les couches supérieures (en général, certains résultat de validation).
Veuillez noter que même la logique de l'exception n'est pas destiné à être utilisé sur une base régulière afin de contrôler le déroulement du programme, mais plutôt de mettre en lumière la situation lorsque le débit devrait vraiment fin. Lorsque utilisé en Java, les deux types d'exception sont RuntimeException sous-classes et de la gestion des erreurs est très orientée aspects.
Donc dans la connexion exemple, il peut être judicieux de créer quelque chose comme AuthenticationException et de distinguer les situations concrètes par les valeurs de l'enum comme UsernameNotExisting, PasswordMismatch etc. Ensuite, vous n'aurez pas à avoir une énorme exception de la hiérarchie et peut garder les blocs catch sur maintenable niveau. Vous pouvez également facilement employer des génériques exception d'un mécanisme de gestion puisque vous avez les exceptions classés et savent très bien ce à propager jusqu'à l'utilisateur et comment.
Notre utilisation typique est de jeter le LogicalException lors de l'appel de Service Web lorsque l'entrée de l'utilisateur n'est pas valide. L'Exception est convoquée pour le type soapfault détail, puis se unmarshalled à l'exception à nouveau sur le client qui se traduit dans le fait de montrer l'erreur de validation sur une certaine page web champ de saisie depuis l'exception a la configuration appropriée pour ce champ.
Ce n'est certainement pas la seule situation: vous n'avez pas besoin de frapper service web pour jeter l'exception. Vous êtes libre de le faire en toute situation exceptionnelle (comme dans le cas où vous avez besoin de fail-fast) - c'est tout à votre discrétion.
la raison principale pour éviter de lancer une exception est qu'il y a beaucoup de frais généraux impliqués avec la levée d'une exception.
Une chose que l'article ci-dessous est qu'une exception est une des conditions exceptionnelles et des erreurs.
Un mauvais nom d'utilisateur n'est pas nécessairement une erreur de programme, mais une erreur de l'utilisateur...
Ici est un bon point de départ pour des exceptions à l'intérieur .NET:
http://msdn.microsoft.com/en-us/library/ms229030(SV.80).aspx
De lever des exceptions causes de la pile pour se détendre, ce qui a des incidences sur la performance (admis, moderne environnements gérés ont progressé par qui). Encore plus d'une fois lancer et attraper les exceptions dans un imbriquée situation serait une mauvaise idée.
Probablement plus important que cela, des exceptions sont faites pour des conditions exceptionnelles. Ils ne doivent pas être utilisés pour les flux de contrôle, parce que cela va nuire à la lisibilité de votre code.
J'ai trois types de conditions que j'ai prises.
Incorrect ou manquant d'entrée ne doit pas être une exception. Utiliser à la fois côté client et js côté serveur regex pour détecter, des attributs et de l'arrière vers l'avant à la même page avec les messages.
La AppException. C'est généralement une exception que vous le détecter et de le jeter dans votre code. En d'autres termes ce sont ceux que vous attendez (le fichier n'existe pas). Journal, il suffit de mettre le message, et de l'arrière vers l'avant à l'erreur générale de la page. Cette page a habituellement un peu d'info sur ce qui s'est passé.
L'Exception inattendue. Ce sont ceux que vous ne connaissez pas. Journal avec les détails et de les transférer à un général page d'erreur.
Espère que cette aide
De sécurité est confondue avec votre exemple: Vous ne devriez pas dire à un attaquant qu'un nom d'utilisateur existe, mais le mot de passe est erroné. C'est extra d'informations que vous n'avez pas besoin de partager. Il suffit de dire "le nom d'utilisateur ou mot de passe est incorrect."
La réponse est simple, chaque fois qu'une opération est impossible (à cause de l'application OU parce que cela serait contraire à la logique d'entreprise). Si une méthode est invoquée et qu'il est impossible de faire ce que la méthode a été écrit pour faire, de lever une Exception. Un bon exemple est que les constructeurs lancent toujours ArgumentExceptions si une instance ne peut pas être créé à l'aide des paramètres fournis. Un autre exemple est InvalidOperationException, qui est générée lorsqu'une opération ne peut pas être effectuée en raison de l'état d'un autre membre ou à des membres de la classe.
Dans votre cas, si la méthode Login(nom d'utilisateur, mot de passe) est invoquée, si le nom d'utilisateur n'est pas valide, il est juste à un jet de UserNameNotValidException, ou PasswordNotCorrectException si le mot de passe est incorrect. L'utilisateur ne peut pas être connecté à l'aide du paramètre fourni(s) (c'est à dire que c'est impossible parce que cela serait contraire à l'authentification), afin de lever une Exception. Bien que je pourrais avoir vos deux Exceptions héritent de ArgumentException.
Cela dit, si vous souhaitez ne PAS lever une Exception si un échec de connexion peut être très commun, une stratégie consiste à créer à la place une méthode qui retourne les types qui représentent les différents échecs. Voici un exemple:
La plupart des développeurs sont appris à éviter les Exceptions en raison de la surcharge causée par les jeter. C'est génial d'être conscient, mais généralement pas au détriment de la conception de votre application. C'est probablement la raison qui vous a dit de ne pas jeter vos deux Exceptions près. Si l'utilisation des Exceptions ou non arrête généralement à la fréquence de l'Exception se produit. Si c'est un assez commun ou assez prévisible résultat, c'est quand la plupart des développeurs va éviter les Exceptions et créer à la place une autre méthode pour indiquer l'échec, en raison de la prétendue consommation de ressources.
Voici un exemple d'éviter l'utilisation des Exceptions dans un scénario comme vient de le décrire, à l'aide de l'Essayer() motif:
À mon avis, la question fondamentale est de savoir si l'on pourrait s'attendre à ce que l'appelant aurait envie de continuer flux de programme normal si une condition se produit. Si vous ne savez pas, soit ont séparé doSomething et trySomething méthodes, où le premier renvoie une erreur et que ce dernier n'a pas, ou avoir une routine qui accepte un paramètre pour indiquer si une exception doit être levée si elle échoue). Considérons une classe pour envoyer des commandes à un système distant et les réponses de rapport. Certaines commandes (par exemple, redémarrer le système à distance pour envoyer une réponse, mais alors non réactif pendant un certain laps de temps. Il est donc utile d'être en mesure d'envoyer une commande "ping" et de savoir si le système distant répond dans un délai raisonnable, sans avoir à lancer une exception si ce n'est pas (l'appelant serait probablement s'attendre à ce que les premiers "ping" tentatives échouaient, mais on finirait par le travail). D'autre part, si l'on a une séquence de commandes telles que:
on souhaite l'échec de toute opération à annuler l'ensemble de la séquence. Alors que l'on pourrait vérifier chaque opération afin de s'assurer qu'il a réussi, il est plus utile d'avoir l'exchange_command() de la routine de lever une exception si une commande échoue.
En fait, dans le scénario ci-dessus, il peut être utile d'avoir un paramètre pour sélectionner un numéro de l'échec des modes de manutention: ne jamais lancer des exceptions, lancer des exceptions pour les erreurs de communication seulement, ou de lancer des exceptions dans tous les cas où une commande ne retourne pas une "réussite" de l'indication.
pour moi une Exception doit être levée lorsque requis techniques ou des affaires d'échec de la règle.
par exemple, si une voiture entité est associée à la matrice de 4 pneus ... si l'on tire ou plus sont nulles ... une exception devrait être Congédié "NotEnoughTiresException" , car il peut être pris à différents niveaux du système et avoir un grand sens grâce à la consignation.
en outre, si nous essayons juste de flux de contrôle de la valeur null et empêcher l'instanciation de la voiture .
nous pourrions ne jamais ne jamais trouver la source du problème , parce que le pneu n'est pas censé être null dans la première place .
Vous pouvez utiliser un peu d'exceptions génériques pour que les conditions. Par exemple ArgumentException est destiné à être utilisé quand quelque chose va mal avec les paramètres d'une méthode (à l'exception de ArgumentNullException). Généralement, vous n'auriez pas besoin des exceptions comme le LessThanZeroException, NotPrimeNumberException etc. Penser à l'utilisateur de votre méthode. Le nombre des conditions qui elle voudra poignée particulièrement est égal au nombre de type de l'exception que votre méthode doit pour lancer. De cette façon, vous pouvez déterminer la façon dont les exceptions détaillées que vous aurez.
Par la route, toujours essayer de fournir des moyens pour que les utilisateurs de vos bibliothèques pour éviter les exceptions. TryParse est un bon exemple, il existe de sorte que vous n'avez pas à utiliser int.Analyser et attraper une exception. Dans votre cas, vous souhaiterez peut-être fournir des méthodes pour vérifier si le nom d'utilisateur est valide ou mot de passe est correct de sorte que vos utilisateurs (ou vous) ne pas avoir à faire beaucoup de la gestion des exceptions. Ce sera on l'espère, dans plus readble code et de meilleures performances.
Finalement, la décision revient à savoir s'il est plus utile de traiter au niveau de l'application des erreurs comme ceci en utilisant la gestion des exceptions, ou par l'intermédiaire de votre propre maison laminé mécanisme comme le retour des codes d'état. Je ne pense pas qu'il y a un dur et rapide de la règle sur ce qui est mieux, mais je considère:
Il existe deux classes principales d'exception:
1) Système d'exception (par exemple la connexion de Base de données perdues) ou
2) l'Utilisateur d'exception. (par exemple, validation des entrées de l'Utilisateur, le mot de passe est incorrect")
Je l'ai trouvé utile de créer ma propre Classe d'Exception et quand je veux lancer une erreur de l'utilisateur, je veux être traitées différemment (c'est à dire de ressources d'erreur affiché à l'utilisateur), alors tout ce que je dois faire dans mon principal gestionnaire d'erreur est de vérifier le type de l'objet:
Quelques choses à penser au moment de décider si une exception est le cas:
quel est le niveau de code que vous voulez être exécutée après l'exception candidat se produit - qui est, combien de couches de la pile d'appel devrait se détendre. En général, vous voulez gérer une exception aussi près que possible de l'endroit où il se produit. Pour le nom d'utilisateur/mot de passe de validation, vous le feriez normalement gérer les défaillances dans le même bloc de code, plutôt que de laisser une exception de la bulle vers le haut. Si une exception est probablement pas approprié. (Otoh, que, après trois tentatives infructueuses de connexion, flux de contrôle peut se déplacer ailleurs, et une exception peut être approprié ici.)
Est cet événement quelque chose que vous voulez voir dans un journal d'erreur? Pas chaque exception est écrit dans un journal d'erreur, mais il est utile de se demander si cette entrée dans un journal d'erreur serait utile - c'est à dire, vous essayez de faire quelque chose à ce sujet, ou serait les ordures que vous ignorer.
"PasswordNotCorrectException" n'est pas un bon exemple pour l'utilisation d'exceptions. Utilisateurs d'avoir leur mot de passe erroné est à prévoir, il n'est donc pas une exception à mon humble avis. Vous avez probablement même la récupérer, montrant un beau message d'erreur, donc c'est juste un contrôle de validité.
Les exceptions non gérées va arrêter l'exécution à la fin - ce qui est bon. Si vous êtes de retour false, null ou les codes d'erreur, vous aurez à traiter avec l'état du programme à tous par vous-même. Si vous oubliez de vérifier que les conditions quelque part, votre programme peut continuer à fonctionner avec des données fausses, et vous pouvez avoir un moment difficile de déterminer ce qui s'est passé et où.
Bien sûr, vous pourriez provoquer le même problème avec vide instructions catch, mais au moins, le spotting est plus facile et ne vous obligent pas à comprendre la logique.
Donc comme une règle du pouce:
Utiliser où vous ne voulez pas ou ne peuvent tout simplement pas se remettre d'une erreur.
Les exceptions et retourner le code d'erreur d'argument devrait être d'environ de contrôle de flux non la philosophie (façon "exceptionnelle" une erreur est):
}
Créer de nouvelles exceptions lorsque vous souhaitez exprimer erreur deux états ou plus dans votre valeur de retour.
Ici sont mes suggestions:
Je ne pense pas que c'est TOUJOURS un bon moyen de lever une exception, car il faudra plus de temps, de mémoire pour traiter avec de telles exceptions.
Dans mon esprit, si quelque chose peut être traitée avec un "gentil,poli" façon (cela signifie que si nous pouvons "prédicat de telles erreurs à l'aide des si...... ou quelque chose de ce genre), nous devrions ÉVITER d'utiliser des "exceptions", mais juste de retour d'un indicateur comme "faux" , avec une enveloppe extérieure valeur du paramètre de dire à lui/elle de l'détaillée de la raison.
En est un exemple, on peut faire une classe comme ce qui suit:
Nous pouvons utiliser ces multiples "valeur renvoyée" classes plutôt que des erreurs, ce qui semble être une meilleure,façon polie de processus, à l'exception des problèmes.
Toutefois, notez que si certaines erreurs ne peuvent pas être décrites de manière facilement (cela dépend de votre expérience de la programmation) avec des "si"......(comme FileIO exceptions), vous devez jeter des exceptions.