web-dev-qa-db-fra.com

Quand et pourquoi vous devez utiliser void (au lieu par exemple de bool / int)

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, il fonctionne 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 renvoyer quelque chose comme un bool ou int, plutôt que de simplement 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 renvoyer true en 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 avez pour 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 obtenu false en raison 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?

30
Independent

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 paradigme de préfixe Try- utilisé dans divers dans les méthodes .NET.

Par exemple, une méthode void InsertRow() pourrait 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 une bool TryInsertRow() qui retourne false 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.

32
Bubblewrap

À 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 tout à fait 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 un peut décide 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.

28
Péter Török

La réponse de Peter couvre bien les exceptions. Les autres considérations ici impliquent 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 ne doivent renvoyer et non modifier l'état. Cela maintient la sémantique très claire et aide à 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.

14
Andy Lowry

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 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.

3
refro

J'écrivais beaucoup de fonctions nulles. Mais depuis que j'ai commencé toute la méthode pour 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.

1
Wyatt Barnett