Est-ce une mauvaise pratique de réutiliser les paramètres de méthode?

12

Il y a des moments où je devrai modifier une valeur passée dans une méthode à partir de la méthode elle-même. Un exemple serait d'assainir une chaîne telle que cette méthode ici:

void SanitizeName(string Name)
{
    Name = Name.ToUpper();

    //now do something here with name
}

Ceci est purement inoffensif car l' Nameargument n'est pas transmis par référence. Cependant, si, pour une raison quelconque, un développeur décide à l'avenir de faire passer toutes les valeurs par ref, tout nettoyage de la chaîne affectera la valeur en dehors de la méthode, ce qui pourrait avoir des résultats préjudiciables.

Par conséquent, au lieu de réaffecter à l'argument lui-même, je crée toujours une copie locale comme ceci:

void SanitizeName(string Name)
{
    var SanitizedName = Name.ToUpper();

    //now do something here with name
}

Cela garantit que la modification de la valeur ne sera jamais affectée en dehors de la méthode, mais je me demande si je suis excessivement paranoïaque à ce sujet.

oscilatingcretin
la source
1
Oui, c'est une mauvaise pratique; et non ce n'est pas inoffensif. La ligne Name = Name.ToUpper();rend le code plus difficile à suivre dans votre tête car la valeur des Namechangements. Votre deuxième exemple est non seulement plus évolutif, il est plus facile de raisonner ce qu'il fait.
David Arno
2
Mais qu'en est-il if (param == NULL) param = default_value;?
aragaer
Je pense que ce n'est pas aussi simple que oui / non.
MrSmith42
3
Si "un développeur à l'avenir décide de faire passer toutes les valeurs par ref" , j'aurais probablement un argument avec ce dev, réutilisation des paramètres impliquée ou non ;-) Honnêtement, quand on décide de passer une valeur by refqui n'a pas été transmise, manière préalable, et donc de convertir un accès local en un accès non local pour une raison quelconque, il doit toujours en vérifier soigneusement les conséquences.
Doc Brown
2
Je travaille principalement dans un paradigme où nous ne réaffectons jamais de variables. Déjà. C'est drôle d'imaginer quelqu'un qui a du mal à réaffecter une petite minorité de variables et à ne pas s'inquiéter de se déchaîner avec le reste.
Karl Bielefeldt

Réponses:

10

Je pense que cela dépend de vos conventions de codage dans votre projet.

Personnellement, je laisse eclipse ajouter automatiquement le finalmot - clé à chaque variable et paramètre. De cette façon, vous voyez au premier coup d'œil si un paramètre est réutilisé.

Dans le projet à mon travail, nous ne recommandons pas de réutiliser les paramètres, mais si vous voulez simplement appeler par exemple .trim()ou définir une valeur par défaut dans un nullcas, nous réutilisons le paramètre la plupart du temps, car l'introduction d'une nouvelle variable est dans ce cas moins lisible que la réutilisation du paramètre.

Vous ne devriez vraiment pas réutiliser un paramètre pour stocker un contenu très différent car le nom ne ferait plus référence à son contenu. Mais cela est vrai pour chaque réaffectation d'une variable et n'est pas limité aux paramètres.

Alors, réunissez-vous avec votre équipe et formulez des conventions de codage qui couvrent ce sujet.

MrSmith42
la source
0

Si vous utilisez un analyseur de code statique à des fins de sécurité, il peut devenir confus et vous pensez que vous n'avez pas validé ou aseptisé la variable de paramètre d'entrée avant de l'utiliser. Si vous utilisez Namedans une requête SQL, par exemple, il pourrait revendiquer une vulnérabilité d'injection SQL, ce qui vous coûterait du temps à expliquer. C'est mauvais. D'un autre côté, l'utilisation d'une variable nommée distinctement pour l'entrée filtrée, sans réellement filtrer l'entrée, est un moyen rapide de calmer les analyseurs de code naïfs (constat de vulnérabilité faussement négative).

Greg
la source
Dans la plupart des cas, vous pouvez également utiliser une sorte d'annotation ou de commentaire spécial pour indiquer à l'analyseur de code que cela est prévu et non un risque inaperçu.
MrSmith42
0

La réponse à cela dépend à 100% de qui va lire votre code. Quels styles trouvent-ils les plus utiles?

J'ai trouvé que le cas le plus général est que l'on évite de réaffecter des valeurs aux arguments de fonction parce que trop de développeurs ont des modèles mentaux de la façon dont fonctionne l'appel de fonction qui supposent que vous ne faites jamais cela. Ce problème peut être exacerbé par les débogueurs qui affichent les valeurs des arguments avec lesquels vous appelez chaque fonction. Ces informations ne sont techniquement pas correctes si vous modifiez les arguments, ce qui peut entraîner d'étranges frustrations.

Cela dit, les modèles mentaux changent. Dans votre environnement de développement particulier, il peut être souhaitable d'avoir name"la meilleure représentation du nom à ce stade". Il peut être souhaitable de lier plus explicitement les variables sur lesquelles vous travaillez à leurs arguments, même si vous avez apporté quelques modifications à leurs valeurs en cours de route. La réutilisation de certaines variables particulières peut même présenter des avantages substantiels à l'exécution plutôt que de créer des objets plus volumineux. Après tout, lorsque vous travaillez avec des chaînes de 4 Go, il est bon de minimiser le nombre de copies supplémentaires que vous devez faire!

Cort Ammon
la source
-1

J'ai un problème complètement différent avec votre exemple de code:

Le nom de votre méthode est SanitizeName. Dans ce cas, je m'attends à ce qu'il désinfecte un nom ; parce que c'est ce que vous dites au lecteur de votre fonction.

La seule chose que vous devez faire est de désinfecter un nom donné . Sans lire votre code, je m'attendrais à ce qui suit:

string SanitizeName(string Name)
{
    //somehow sanitize the name
    return Result;
}

Mais vous laissez entendre, que votre méthode fait un peu plus que sanitizng. C'est une odeur de code et devrait être évitée.

Votre question ne concerne pas: est-ce une mauvaise pratique de réutiliser les paramètres de méthode? C'est plus: les effets secondaires et les comportements inattendus sont-ils une mauvaise pratique?

La réponse est clairement: oui!

Ceci est purement inoffensif car l'argument Name n'est pas transmis par référence. Cependant, si, pour une raison quelconque, un développeur décide à l'avenir de faire passer toutes les valeurs par ref, tout nettoyage de la chaîne affectera la valeur en dehors de la méthode, ce qui pourrait avoir des résultats préjudiciables.

Vous induisez votre lecteur en erreur en ne renvoyant rien. Le nom de votre méthode indique clairement que vous faites quelque chose Name. Alors, où devrait aller le résultat? Par votre fonction, la signature voidindique que j'utilise, Namemais ne nuit pas à id, ni ne vous informe du résultat (explicitement). Il y a peut-être une exception levée, peut-être pas; mais Namen'est pas modifié . C'est l'opposé sémantique du nom de votre méthode.

Le problème est moins la réutilisation que les effets secondaires . Pour éviter les effets secondaires , ne réutilisez pas une variable. Si vous n'avez aucun effet secondaire, il n'y a pas de problème.

Thomas Junk
la source
4
-1 Cela ne répond pas à la question d'origine. Le code fourni n'est qu'un exemple de code pour montrer la question à portée de main. Veuillez répondre à la question, au lieu "d'attaquer" / de revoir l'exemple de code fourni.
Niklas H
1
@NiklasH Cela répond parfaitement à la question: si vous manipulez le paramètre à l'intérieur de la fonction et comme le TO l'a mentionné, vous travaillez accidentellement avec une référence au lieu d'une copie, cela provoque des effets secondaires (comme je l'ai dit) et c'est mauvais. Pour éviter cela, indiquez que vous allez modifier la variable en choisissant soigneusement le nom de la méthode (pensez au Ruby '!') Et / ou en choisissant un type de retour. Si vous ne modifiez pas la variable, ne travaillez qu'avec des copies.
Thomas Junk