Juste curieux si quelqu'un a des opinions sur la mise en place d'une exception dans ma mise en œuvre de la totrage ultérieure. Mon instinct me dit que cela pourrait être une mauvaise pratique, mais je ne semble pas être capable de trouver quoi que ce soit de soutien si c'est mauvais ou non. P>
Toutes les pensées? p>
Code: http://pastebin.com/mlekbaaz p>
Merci. P>
7 Réponses :
Si l'objet est dans un état invalide, vous devez organiser une exception. Si je vois quelque chose comme un Ma philosophie est que je ne suis pas assez intelligent pour couvrir tous les cas afin que je jette des exceptions pour m'aider et d'autres programmeurs capturer des erreurs tôt. Également connu sous le nom de Fast Fast Strong> Philosophie. P> NullReferenceException code>, bien, disons simplement que je ne serai pas impressionné. P>
Strictement parlant, une exception doit être lancée avant même que l'objet ne soit même autorisé à entrer dans un état invalide. En fait, aucun objet ne devrait jamais être dans un état invalide. Si tel est le cas, il devrait y avoir une propriété d'indicateur indiquant que c'est ou devrait suivre le motif de la machine à états.
@Rei: C'est ce que j'essaie de dire.
Il y a une différence entre un état non valide et un état inutilisable. S'assurer qu'un objet est toujours dans un état utilisable n'est souvent pas possible, mais garantissant qu'un objet est toujours dans un état valide est en fait très faisable dans le monde réel. Après tout, nous parlons d'ordinateurs ici - Enregistrez-vous des échecs matériels ou des bogues de gestion de la mémoire, nous sommes bons.
@Rei - Vous n'avez pas à me dire, 90% des objets que j'écris sont immuables.
Je ne le ferais pas. Je ne vois aucune situation où il serait préférable d'avoir un Vous utilisez généralement beaucoup de appels .Tostring () à des fins de débogage.
Maintenant, disons que vous avez débogué votre code et essayons d'attraper un bug. Non seulement votre code de buggy a lancé des exceptions dans des endroits aléatoires, vous devez également prendre soin du problème d'additionnel des représentations de chaînes d'objet, lancant des exceptions. P>
Donc, par ce que vous nous dites,
Je ne voudrais probablement pas mettre le code que vous mettez dans Tostring () code> Méthode lancez une exception au lieu de, par exemple, renvoyer l'objet
objet.tostring () code> Représentation. P>
EDIT: H2>
.tostring () code>'s. Je trouverais un autre nom de méthode, disons,
.getxmlrepresentation () code> et j'aurais aussi un
.checkifisinvalidstate () code>. Ensuite, je ferais
.getxmlrepresentation () code> lancer une exception si vous avez essayé de l'appeler dans un état non valide. Mais j'aimerais utiliser
.tostring () code> pour d'autres types d'objectifs. P>
Et si vous avez un objet mutable avec un état valide. Si vous n'êtes pas dans un état valide, je m'attendrais à ce qu'il jette une exception détaillée.
Dans la méthode .Tostring ()? L'idée de la méthode .Tostring () n'est pas de vérifier si l'objet est dans un bon état. Si c'est dans un état invalide, imprimez-la comme chaîne! C'est ce que vous voudrez voir lorsque vous déboguez, par exemple.
Et si vous n'utilisez pas tostring code> pour le débogage? Dans Visual Studio, vous pouvez attraper toutes les exceptions non contenues au point qu'ils sont lancés. Et si vous oubliez de vérifier le résultat et tout soudain à un autre point de votre code, le bogue se révèle enfin.
Mais pourquoi le bogue devrait-il se révéler quand vous appelez .Tostring (), en premier lieu? La méthode .Tostring () doit être la dernière place que vous rechercheriez une exception. Vous devriez rechercher les invariants de l'objet pour vérifier l'état non valide, puis élever des exceptions, ce qui n'attend pas un appel à .tostring ().
Les objets mutables peuvent avoir de nombreux états non valides. Et si vous avez oublié de définir une propriété sur l'objet?
Ce que je veux dire, c'est que si l'objet est dans un état invalide, ce n'était pas à cause d'appeler .Tostring (). Si ce n'était pas à cause d'appeler .Tostring (), vous devriez alors lancer l'exception à l'endroit où l'état invalide a été introduit, vous pouvez donc facilement trouver ce qui s'est mal passé.
Ma classe est une représentation d'un querymodel. Pour exécuter la requête cependant, il doit être une chaîne XML. Donc, j'utilise Tostring () pour formater mon objet dans XML afin qu'il puisse être exécuté. Cependant, si mon objet n'est pas dans un état valide, je ne veux pas que la requête soit courue. C'est pourquoi c'est pourquoi je jette l'exception. Je ne sais pas comment mieux représenter mon objet pour Tostring, autre que le format XML. Et je ne veux pas que le XML soit exécuté si c'est invalide, donc donc l'exception. Les pensées?
@Tehone - Je pense que c'est très raisonnable. Ma philosophie est que je ne suis pas assez intelligent pour couvrir tous les cas, alors je jette des exceptions.
Pourquoi ne mettez-vous pas une méthode appelée checkifisinvalidstate () ou quelque chose?
Je conviens que c'est une mauvaise idée de jeter une exception dans Tostring (), s'il s'agit d'une représentation XML, puis implémentez une nouvelle méthode comme TOXMLQuery () ou quelque chose comme ça, puis vous pouvez vous lancer une exception à partir de là.
Je ne voudrais probablement pas mettre le code que vous mettez en .tostring (). Je trouverais un autre nom de méthode, disons, .getxmlrepresentation () et j'aurais aussi un .checkifisinvalidstate (). Ensuite, je ferais .GETXMLrePresentation () lancer une exception si vous avez essayé de l'appeler dans un état invalide. Mais j'aimerais utiliser .Tostring () pour d'autres types d'usages.
J'ai mis à jour le message avec un lien vers le code. Je pensais faire une méthode toxmlquiery () ou quelque chose comme ça, mais je ne sais alors pas à la façon dont je voudrais faire une meilleure utilisation de ToString pour une représentation précise de mon objet, c'est pourquoi je viens d'utiliser Tostring dans le première place. Mon objet n'a pas d'autre que d'autres utilisent ensuite comme XML à soumettre à un service Web.
Si cela ne se comporte que comme une valeur, il ne devrait pas avoir la responsabilité de lancer des exceptions en premier lieu. Ce devrait être la classe qui fait en réalité quelque chose qui a cette responsabilité.
Après avoir examiné le code, je pense que l'objet doit être refacturé de ne pas lancer d'exceptions. Cependant, je supporte toujours mon opinion qu'il est valide pour lancer des exceptions dans Tostring code> de manière défensive. Il est important de se rappeler qu'il existe toujours des exceptions aux règles de programmation rigoureuses et rapides.
Je suis d'accord avec @jeff t et @Devourded Elysium. Tostring devrait représenter l'objet à des fins d'information. Ceci est un cas de sérialisation, pas d'affichage ("afin qu'il puisse fonctionner"). Vous ne remplissez pas la mise en œuvre i> de Tostring (), vous remplacez le but i> pour Tostring (). Cela enfreint l'esprit de l'interface car vous modifiez essentiellement le type de retour d'une chaîne (texte brut) à XML.
@JIM: Vous l'avez résumée avec la phrase suivante: «Vous ne remplissez pas la mise en œuvre de Tostring (), vous remplacez le but de Tostring ()»
Merci pour toutes les opinions les gars. J'ai renommé ma méthode et je ne vais tout simplement pas remplacer pour maintenant. Comme je l'ai dit dans la question, je me suis déjà senti comme si je faisais une erreur, et j'ai maintenant reçu assez d'opinions pour me faire corriger. Merci encore tout le monde.
Je dirais que c'est une mauvaise idée. Si l'objet est dans un état non valide, il doit y avoir un point sur lequel il est arrivé là-bas - c'est là que vous devriez lancer, pas lorsque vous le convertissez en chaîne. IMO, tout objet doit avoir une représentation de chaîne valide à tout moment, même s'il s'agit de l'automate par défaut (nom de classe de l'objet). P>
Un objet ne doit jamais être dans un état invalide. L'objet devrait lancer une exception dès que le consommateur tente de définir un état invalide sur celui-ci. P>
Votre objet pourrait être dans un état inutilisable em> (dire qu'il s'agit d'un objet de connexion de base de données, et il n'a pas encore connecté), auquel cas il devrait avoir un drapeau isconnecté, ou il devrait suivre le modèle de machine d'état afin que l'état de l'objet soit toujours valable à son droit. P >
Et puisque votre surcharge de tostring () ne prend probablement aucun argument, il ne devrait jamais être la faute de l'appelant qu'elle lancerait une exception. P>
Par conséquent, non, je ne peux penser à aucune exception que ToString () lancerait. P>
EDIT STRUT>: Dans le cas du code Pastebin, le meilleur moyen de faire ce problème serait de consolider les paramètres de la requête dans une classe distincte - appelez-le desparametteurs ou quelque chose. P >
peupler cela en premier, puis transmettez-le dans une classe qui générera le code SQL. Si lorsque vous passez l'objet SearchParameters dans la recherchequery (probablement via le constructeur afin que vous puissiez le rendre immuable) Les paramètres sont invalides, vous pouvez y jeter une exception. P>
De cette façon si votre objet de recherchequery ait jamais eu plus de méthodes qui s'appuient sur une requête de recherche valide, vous n'aurez pas besoin de répéter le code de validation, et bien sûr, Tostring () ne jettera jamais une exception. P >
exceptions font partie du contrat de Comme vous l'avez dit, si une autre exception est lancée, ce sera une surprise. Les programmeurs n'aiment pas les surprises. P> Object code> 'S
TOSTRING code> et, en tant que telle, toutes les exceptions projetées par des implémentations de classe dérivée ne doivent pas différer à celles projetées par la base La mise en œuvre de la classe, à mon avis. Je ne pense pas que
TOSTRING code> jette un type d'exception dans l'une des classes de BCL de base Microsoft Base, alors je sert à cette convention. P>
TOSTRING () est une méthode comme tout autre, donc si vous souhaitez signaler un problème dans son exécution, vous devez organiser une exception (comme d'habitude, ne forte> utilise des exceptions pour exprimer la logique ou le retour résultats). Si, à mesure que l'éliminalie mentionne, le débogage devient problématique, vous pouvez marquer la méthode Tostring () avec l'attribut debuggerstePthrough. P>
La méthode .Tostring () ne doit pas faire de opération i> sur l'objet / système, imo. S'il ne peut pas changer l'état de l'objet, pourquoi devrait-il avoir la responsabilité de jeter des exceptions? Je pense que beaucoup de confusion provient de la méthode de Stringbuilder .Tostring () que je trouve maladroitement. D'une part, il va avec le reste de la convention .NET d'avoir des méthodes de .toxxx lorsque vous souhaitez convertir en un type de données. D'autre part, .Tostring () est considéré comme une méthode spéciale dans le cadre, alors je pense que peut-être un stringbuilder.buildstring () aurait pu être un nom plus sugguissant et causer moins de ravages.
gendarme (un outil d'analyse statique) a un QUI STATS: P>
objet.tostring - Celles-ci sont appelées par le débogueur pour afficher des objets et sont également souvent utilisées avec le débogage de style Printf afin de ne pas changer l'état de l'objet et ne doivent pas lancer. p>
blockQuote>
À peine officielle par Microsoft, mais c'est un très bon indicateur que ce serait une pratique médiocre de jeter dans une méthode
tostring code>. p>
Juste au cas où mon point sous-jacent était perdu dans le débat, n'oubliez pas d'échouer rapidement. Pas seulement pour vous-même mais pour tous ceux qui travailles avec vous. (Je me sens comme un imbécile pour que ce débat a commencé ... Je ne peux vraiment pas penser à une fois que j'ai réellement jeté une exception dans Tostring ...) I>
Microsoft dit
Tostring () Code> Les remplissages ne doivent pas lancer d'exceptions: docs.microsoft.com/en-us/dotnet/api/...