Je rencontre parfois des méthodes où un développeur a choisi de renvoyer quelque chose qui n'est pas critique pour la fonction. Je veux dire, quand on regarde le code, ça marche apparemment aussi bien qu'un void
et après un moment de réflexion, je demande "Pourquoi?" Cela vous semble-t-il familier?
Parfois, je conviens que le plus souvent, il vaut mieux retourner quelque chose comme un bool
ou int
plutôt que de faire un void
. Je ne suis pas sûr cependant, dans l'ensemble, des avantages et des inconvénients.
Selon la situation, le renvoi d'un int
peut rendre l'appelant conscient du nombre de lignes ou d'objets affectés par la méthode (par exemple, 5 enregistrements enregistrés dans MSSQL). Si une méthode comme "InsertSomething" renvoie un booléen, je peux avoir la méthode conçue pour retourner en true
cas de succès, sinon false
. L'appelant peut choisir d'agir ou non sur ces informations.
D'autre part,
- Peut-il conduire à un objectif moins clair d'un appel de méthode? Un mauvais codage m'oblige souvent à revérifier le contenu de la méthode. S'il retourne quelque chose, il vous indique que la méthode est d'un type que vous devez faire quelque chose avec le résultat renvoyé.
- Un autre problème serait, si l'implémentation de la méthode vous est inconnue, qu'est-ce que le développeur a décidé de renvoyer qui ne soit pas critique? Bien sûr, vous pouvez le commenter.
- La valeur de retour doit être traitée, lorsque le traitement pourrait être terminé à la parenthèse fermante de la méthode.
- Que se passe-t-il sous le capot? La méthode appelée a-t-elle été récupérée à
false
cause d'une erreur levée? Ou est-elle retournée fausse en raison du résultat évalué?
Quelles sont vos expériences avec cela? Comment agiriez-vous là-dessus?
la source
void
au moins permet au développeur de savoir que la valeur de retour de la méthode est sans conséquence; il fait une action, plutôt que de calculer une valeur.Réponses:
Dans le cas d'une valeur de retour bool pour indiquer le succès ou l'échec d'une méthode, je préfère le
Try
paradigme -prefix utilisé dans divers dans les méthodes .NET.Par exemple, une
void InsertRow()
méthode peut lever une exception s'il existe déjà une ligne avec la même clé. La question est, est-il raisonnable de supposer que l'appelant s'assure que sa ligne est unique avant d'appeler InsertRow? Si la réponse est non, je fournirais également unbool TryInsertRow()
qui renvoie faux si la ligne existe déjà. Dans d'autres cas, tels que des erreurs de connectivité db, TryInsertRow peut toujours lever une exception, en supposant que le maintien de la connectivité db est la responsabilité de l'appelant.la source
À mon humble avis, le renvoi d'un "code d'état" provient de l'époque historique, avant que les exceptions ne deviennent monnaie courante dans les langages de niveau intermédiaire à supérieur tels que C #. De nos jours, il est préférable de lever une exception si une erreur inattendue a empêché votre méthode de réussir. De cette façon, il est sûr que l'erreur ne passe pas inaperçue, et l'appelant peut la traiter comme il convient. Donc, dans ces cas, il est parfaitement correct qu'une méthode ne retourne rien (c'est-à-dire
void
) au lieu d'un indicateur d'état booléen ou d'un code d'état entier. (Bien sûr, il faut documenter les exceptions que la méthode peut lancer et quand.)D'un autre côté, s'il s'agit d'une fonction au sens strict, c'est-à-dire qu'elle effectue un calcul basé sur des paramètres d'entrée et qu'elle devrait renvoyer le résultat de ce calcul, le type de retour est évident.
Il y a une zone grise entre les deux, quand on peut décider de renvoyer des informations "supplémentaires" de la méthode, si cela est jugé utile pour ses appelants. Comme votre exemple sur le nombre de lignes affectées dans un insert. Ou pour qu'une méthode place un élément dans une collection associative, il peut être utile de renvoyer la valeur précédente associée à cette clé, s'il y en avait. De telles utilisations peuvent être identifiées en analysant soigneusement les scénarios d'utilisation (connus et prévus) d'une API.
la source
La réponse de Peter couvre bien les exceptions. D'autres considérations ici impliquent la séparation commande-requête
Le principe CQS dit qu'une méthode doit être soit une commande, soit une requête et non les deux. Les commandes ne doivent jamais renvoyer une valeur, ne modifient que l'état et les requêtes doivent uniquement renvoyer et non modifier l'état. Cela permet de garder la sémantique très claire et de rendre le code plus lisible et maintenable.
Il y a quelques cas où la violation du principe CQS est une bonne idée. Celles-ci concernent généralement les performances ou la sécurité des threads.
la source
Quel que soit le chemin, vous allez marcher avec ça. Ne contient pas de valeurs de retour pour une utilisation future (par exemple, les fonctions retournent toujours true), c'est un gaspillage d'effort terrible et ne rend pas le code plus clair à lire. Lorsque vous avez une valeur de retour, vous devez toujours l'utiliser, et pour pouvoir l'utiliser, vous devez avoir au moins 2 valeurs de retour possibles.
la source
J'avais l'habitude d'écrire beaucoup de fonctions nulles. Mais depuis que j'ai commencé toute la méthode à enchaîner le crack, j'ai commencé à retourner cela plutôt que le vide - autant laisser quelqu'un profiter du retour parce que vous ne pouvez pas faire de squat avec le vide. Et s'ils ne veulent rien en faire, ils peuvent simplement l'ignorer.
la source
Ruby
à un moment donné? C'est ce qui m'a initié au chaînage de méthodes.return Thing.Change1().Change2();
-ci s'attend à changerThing
et à renvoyer une référence à l'original, ou à retourner une référence à une nouvelle chose qui diffère de l'original, tout en laissant le d'origine intacte.