La lecture de l' article d' Eric Lippert sur les exceptions a certainement été une révélation sur la façon dont je devrais aborder les exceptions, à la fois en tant que producteur et en tant que consommateur. Cependant, j'ai toujours du mal à définir une ligne directrice sur la façon d'éviter de lever des exceptions vexantes.
Plus précisément:
- Supposons que vous ayez une méthode Save qui peut échouer car a) quelqu'un d'autre a modifié l'enregistrement avant vous , ou b) la valeur que vous essayez de créer existe déjà . Ces conditions sont à prévoir et ne sont pas exceptionnelles, donc au lieu de lever une exception, vous décidez de créer une version Try de votre méthode, TrySave, qui renvoie un booléen indiquant si la sauvegarde a réussi. Mais s'il échoue, comment le consommateur saura-t-il quel était le problème? Ou serait-il préférable de renvoyer une énumération indiquant le résultat, sorte de Ok / RecordAlreadyModified / ValueAlreadyExists? Avec integer.TryParse, ce problème n'existe pas, car il n'y a qu'une seule raison pour laquelle la méthode peut échouer.
- L'exemple précédent est-il vraiment une situation épineuse? Ou est-ce que la levée d'une exception dans ce cas serait la meilleure façon? Je sais que c'est ainsi que cela se fait dans la plupart des bibliothèques et des cadres, y compris le cadre Entity.
- Comment décidez-vous quand créer une version Try de votre méthode par rapport à fournir un moyen de tester à l'avance si la méthode fonctionnera ou non? Je suis actuellement en train de suivre ces directives:
- S'il existe un risque de condition de concurrence, créez une version d'essai. Cela évite au consommateur de devoir attraper une exception exogène. Par exemple, dans la méthode Save décrite précédemment.
- Si la méthode pour tester la condition ferait à peu près tout ce que fait la méthode d'origine, créez une version d'essai. Par exemple, integer.TryParse ().
- Dans tous les autres cas, créez une méthode pour tester la condition.