J'ai eu une discussion avec un collègue sur la rupture d'une return
instruction et l'instruction qui calcule la valeur de retour sur deux lignes.
Par exemple
private string GetFormattedValue()
{
var formattedString = format != null ? string.Format(format, value) : value.ToString();
return formattedString;
}
au lieu de
private string GetFormattedValue()
{
return format != null ? string.Format(format, value) : value.ToString();
}
Au niveau du code, je ne vois pas vraiment de valeur dans la première variante. Pour moi, ce dernier est plus clair, en particulier pour les méthodes aussi courtes. Son argument était que la première variante est plus facile à déboguer - ce qui est un assez petit mérite, puisque VisualStudio nous permet une inspection très détaillée des instructions, lorsque l'exécution est arrêtée en raison d'un point d'arrêt.
Ma question est, si c'est toujours un point valide pour écrire du code moins clair, juste pour faciliter le débogage un aperçu? Y a-t-il d'autres arguments pour la variante avec le calcul et l' return
instruction fractionnés ?
la source
private string GetFormattedValue() => string.Format(format ?? "{0}", value);
Réponses:
L'introduction de l'explication des variables est une refactorisation bien connue qui peut parfois aider à rendre les expressions compliquées plus lisibles. Cependant, dans le cas illustré,
De plus, les nouvelles versions du débogueur Visual Studio peuvent afficher la valeur de retour d'une fonction dans la plupart des cas sans introduire de variable superflue (mais attention, il y a quelques mises en garde, jetez un œil à cette ancienne publication SO et aux différentes réponses ).
Donc, dans ce cas spécifique, je suis d'accord avec vous, cependant, il existe d'autres cas où une variable explicative peut en effet améliorer la qualité du code.
la source
result
comme nom de variable. Pas tellement plus long et plus facile à déboguerresult
souvent ajoute juste du bruit au code et augmente rarement la lisibilité, ce qui est exactement le point de ma réponse. Cela peut être justifié dans le contexte où cela aide au débogage, mais j'éviterais d'utiliser un débogueur qui n'a pas besoin d'une variable distincte.result
transmet l'information qu'il s'agit de la valeur résultant de la fonction, afin que vous puissiez la consulter avant le retour de la fonction.Étant donné les faits suivants:
a) Il n'y a aucun impact sur le code final car le compilateur optimise la variable.
b) Le fait de le séparer améliore la capacité de débogage.
Je suis personnellement arrivé à la conclusion que c'est une bonne pratique de les séparer 99% du temps.
Il n'y a aucun inconvénient matériel à le faire de cette façon. L'argument selon lequel il gonfle le code est un terme impropre, car le code gonflé est un problème trivial par rapport au code illisible ou difficile à déboguer. De plus, cette méthode ne peut pas à elle seule créer du code déroutant, cela dépend entièrement du développeur.
la source
Souvent, l'introduction d'une variable juste pour nommer un résultat est très utile lorsqu'elle rend le code plus auto-documenté. Dans ce cas, ce n'est pas un facteur car le nom de la variable est très similaire au nom de la méthode.
Notez que les méthodes d'une ligne n'ont aucune valeur inhérente. Si un changement introduit plus de lignes mais rend le code plus clair, c'est un bon changement.
Mais en général, ces décisions dépendent fortement de vos préférences personnelles. Par exemple, je trouve les deux solutions déroutantes car l'opérateur conditionnel est utilisé inutilement. J'aurais préféré une instruction if. Mais dans votre équipe, vous avez peut-être convenu de différentes conventions. Faites ensuite ce que vos conventions suggèrent. Si les conventions sont muettes sur un cas comme celui-ci, notez qu'il s'agit d'un changement extrêmement mineur qui n'a pas d'importance à long terme. Si ce modèle se répète, vous pouvez peut-être lancer une discussion sur la manière dont vous, en équipe, souhaitez gérer ces cas. Mais cela divise les cheveux entre «bon code» et «peut-être un tout petit peu meilleur code».
la source
?
et d'un:
j'utiliseif() {
et} else {
- - - -\\ :)
En réponse à vos questions:
Ma question est, si c'est toujours un point valide pour écrire du code moins clair, juste pour faciliter le débogage un aperçu?
Oui. En fait, une partie de votre déclaration antérieure me semble (aucune infraction) d'être un peu courte vue (voir gras ci - dessous) " Son argument que ce soit était que la première variante est plus facile à déboguer - ce qui est tout à fait un petit mérite , puisque VisualStudio nous permet une inspection très détaillée des déclarations, lorsque l'exécution est arrêtée en raison d'un point d'arrêt. "
Rendre le débogage plus facile n'est (presque) jamais de " petit mérite " car, selon certaines estimations, 50% du temps d'un programmeur est consacré au débogage ( logiciel de débogage réversible ).
Y a-t-il d'autres arguments pour la variante avec le calcul de fractionnement et l'instruction return?
Oui. Certains développeurs diraient que le calcul fractionné est plus facile à lire. Ceci, bien sûr, aide au débogage mais aide également lorsque quelqu'un essaie de déchiffrer les règles métier que votre code peut exécuter ou appliquer.
REMARQUE: les règles métier peuvent être mieux servies dans une base de données car elles peuvent changer souvent. Néanmoins, un codage clair dans ce domaine est toujours primordial. ( Comment créer un moteur de règles métier )
la source
J'irais encore plus loin:
Pourquoi?
L'utilisation d'opérateurs ternaires pour une logique plus complexe serait illisible, vous utiliseriez donc un style comme celui ci-dessus pour des instructions plus complexes. En utilisant toujours ce style, votre code est cohérent et plus facile à analyser pour un humain. De plus, en introduisant ce type de cohérence (et en utilisant des codes lints et d'autres tests), vous pouvez éviter
goto fail
les erreurs de type.Un autre avantage est que votre rapport de couverture de code vous indiquera si vous avez oublié d'inclure un test pour
format
n'est pas nul. Ce ne serait pas le cas pour l'opérateur ternaire.Mon alternative préférée - si vous êtes dans le "obtenir un retour aussi rapide que possible" et non contre plusieurs retours d'une méthode:
Vous pouvez donc consulter le dernier retour pour voir quelle est la valeur par défaut.
Il est cependant important d'être cohérent et de faire en sorte que toutes vos méthodes suivent l'une ou l'autre convention.
la source
value.ToString()
est appelé inutilement lorsque le format n'est pas nul. Dans le cas général, cela peut inclure des calculs non triviaux et peut prendre plus de temps que la version incluant une chaîne de format. Considérez, par exemple, unvalue
qui stocke PI à un million de décimales et une chaîne de format qui ne demande que les premiers chiffres.private string GetFormattedValue() => string.Format(format ?? "{0}", value);
Même effet, et utilisez des tests unitaires pour garantir l'exactitude au lieu de compter sur le débogueur.Je ne pense pas qu'une telle technique puisse être justifiée par la nécessité de déboguer. J'ai moi-même rencontré cette approche mille fois, et de temps en temps je continue de le faire, mais je garde toujours à l'esprit ce que Martin Fowler a dit à propos du débogage :
la source
Je pense que certaines personnes se bloquent sur des questions tangibles à la question, comme l'opérateur ternaire. Oui, beaucoup de gens détestent ça, alors peut-être que c'est bon de parler de toute façon.
Concernant le centre de votre question, déplacer l'instruction renvoyée pour qu'elle soit référencée par une variable ...
Cette question fait 2 hypothèses avec lesquelles je ne suis pas d'accord:
Que la deuxième variante est plus claire ou plus facile à lire (je dis que le contraire est vrai), et
que tout le monde utilise Visual Studio. J'ai utilisé Visual Studio plusieurs fois et je peux l'utiliser très bien, mais j'utilise généralement autre chose. Un environnement de développement qui force un IDE spécifique est un environnement dont je serais sceptique.
Rendre quelque chose à une variable nommée rend rarement plus difficile la lecture, cela fait presque toujours le contraire. La manière spécifique dont quelqu'un le fait peut causer des problèmes, comme si un suzerain de l'auto-documentation le fait,
var thisVariableIsTheFormattedResultAndWillBeTheReturnValue = ...
c'est évidemment mauvais, mais c'est un problème distinct.var formattedText = ...
c'est bien.Dans ce cas spécifique , et peut-être dans de nombreux cas puisque nous parlons de 1-liners, la variable ne vous dirait pas grand-chose que le nom de la fonction ne vous dit pas déjà. Par conséquent, la variable n'ajoute pas autant. L'argument de débogage pourrait toujours tenir, mais encore une fois, dans ce cas spécifique, je ne vois rien qui soit susceptible d'être votre objectif lors du débogage, et il peut toujours être facilement modifié plus tard si quelqu'un a besoin de ce format pour le débogage ou autre chose.
En général, et vous avez demandé la règle générale (votre exemple était juste cela, un exemple de formulaire généralisé), tous les arguments avancés en faveur de la variante 1 (2 lignes) sont corrects. Ce sont de bonnes directives à avoir. Mais les directives doivent être flexibles. Par exemple, le projet sur lequel je travaille a maintenant un maximum de 80 caractères par ligne, donc je divise beaucoup de lignes, mais je trouve généralement des lignes de 81 à 85 caractères qui seraient difficiles à diviser ou à réduire la lisibilité et je les laisse la limite.
Puisqu'il est peu probable d'ajouter de la valeur, je ne ferais pas 2 lignes pour l'exemple spécifique donné. Je referais la variante 2 (le 1-liner) car les points ne sont pas assez solides pour faire autrement dans ce cas.
la source