Je viens de commencer à utiliser ReSharper avec Visual Studio (après les nombreuses recommandations sur les SO). Pour l'essayer, j'ai ouvert un projet ASP.NET MVC récent. L’une des premières choses les plus fréquentes que j’ai remarquées est de changer la plupart/toutes mes déclarations explicites en var
à la place. Par exemple:
//From This:
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
//To This:
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
et ainsi de suite, même avec des types simples tels que int
, bool
, etc.
Pourquoi est-ce recommandé? Je ne viens pas d'un environnement informatique ou .NET, je suis "tombé dans" le développement .NET récemment, alors j'aimerais vraiment comprendre ce qui se passe et s'il est bénéfique ou non.
Une des raisons est la lisibilité améliorée. Ce qui est mieux?
Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();
ou
var dictionary = new Dictionary<int, MyLongNamedObject>();
Ce que ReSharper suggère est clairement une surutilisation du mot-clé var. Vous pouvez l'utiliser là où le type est évident:
var obj = new SomeObject();
Si le type n'est pas évident, vous devriez plutôt l'écrire:
SomeObject obj = DB.SomeClass.GetObject(42);
Personnellement, je préfère désactiver cette suggestion. Utiliser var
peut souvent améliorer la lisibilité; mais comme vous l'avez mentionné, cela le réduit parfois (avec des types simples ou lorsque le type résultant est obscur).
Je préfère choisir quand j'utilise var
et quand je ne le fais pas. Mais encore une fois, c'est juste moi.
var
peut augmenter la lisibilité du code tout en diminuant sa compréhension immédiate. De la même façon, cela peut diminuer la lisibilité du code pour d’autres situations. Parfois, son utilisation est neutre. La mesure de la lisibilité à la compréhension n'est pas proportionnelle mais dépend de la situation. Parfois, les deux sont augmentés ou diminués ensemble.
Le facteur est ce à quoi var
est appliqué et à quel point la cible prend en charge l'obscurcissement immédiat de son type de données pour le lecteur, ou si ses informations de type sont nécessaires pour comprendre la portion de programme en question.
Par exemple, une mauvaise désignation peut entraîner var
provoquer une diminution de la compréhension du code. Ce n’est pas la faute de var
:
var value1 = GetNotObviousValue(); //What's the data type?
//vs.
var value2 = Math.Abs(-3); // Obviously a numeric data type.
Parfois, il n’a pas de sens d’utiliser var
pour les types de données simples lorsque le code est plus lisible en son absence:
var num = GetNumber(); // But what type of number?
// vs.
double num = GetNumber(); // I see, it's a double type.
Parfois, var
peut être utile pour masquer des informations de type de données dont vous ne vous souciez pas nécessairement de voir les complexités de:
IEnumerable<KeyValuePair<string,List<Dictionary<int,bool>>>> q = from t in d where t.Key == null select t; // OMG!
//vs.
var q = from t in d where t.Key == null select t;
// I simply want the first string, so the last version seems fine.
q.First().Key;
Vous devez utiliser var
lorsqu'il y a un type anonyme présent car il n'y a pas de nom de type pour l'appeler par:
var o = new { Num=3, Name="" };
Lorsque Visual Studio Intellisense fournit des informations sur le type malgré var
, vous devez alors moins vous fier à votre compréhension via une lecture de code stricte sans aide. Il est probablement sage de supposer que tout le monde n’a pas ou n’utilise pas Intellisense.
En résumé, basé sur les exemples ci-dessus, Je suggèrerais l'application d'une carte blanche de var
n'est pas une bonne idée car la plupart des choses sont faites avec modération et en fonction des circonstances montré ici.
Pourquoi Resharper l'utilise-t-il par défaut? Je suggérerais pour la facilité, parce qu'il ne peut pas analyser les nuances des situations pour décider quand mieux ne pas l'utiliser.
Dans ReSharper (8.02, mais probablement d’autres versions), l’option de la suggestion "Utiliser la déclaration de variable locale implicitement typée" peut être ajustée à votre préférence, quelle qu’elle soit, en ouvrant d’abord le menu ReSharper:
Ensuite, sous "Inspection du code" en ajustant la "Gravité de l'inspection" de la langue de votre choix, dans mon cas c #:
Comme vous pouvez le constater, il existe des options pour ajuster toutes les suggestions faites par ReSharper. J'espère que cela aidera quelqu'un comme moi qui a déjà une stratégie d'utilisation 'var' et qui veut juste que ReSharper la respecte :)
Je suis surpris que personne ne mentionne le fait qu'il est également plus facile de changer le type de l'objet instancié, car
AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );
est un forme de répétition. Si je veux changer AVeryLongTypeName
en l'une de ses classes dérivées, je n'ai besoin de le changer qu'une seule fois lorsque j'utilise var
et je peux toujours accéder aux méthodes des classes enfants.
En plus de cela, la lisibilité améliorée est un point important, mais comme d’autres l’ont dit, var ne doit pas être surutilisé, je pense donc que désactiver le soupçon dans Resharper est tout à fait correct.
'var' veut être clair
Le débat principal sur l’utilisation éventuelle du mot clé var
concerne la lisibilité du code pour vous et les autres développeurs.
Tout comme si vous écriviez une histoire, il n’ya pas de bonne réponse définitive. Mais regardons quelques exemples de cela en clair.
Jake a salué Bill. Il ne l'aimait pas alors il se retourna et partit dans l'autre sens.
Qui est allé dans l'autre sens? Jake ou Bill? Dans ce cas, utiliser les noms "Jake" et "Bill" revient à utiliser le nom du type. Et "Lui" et "lui" revient à utiliser le mot clé var
. Dans ce cas, il peut être utile d’être plus précis. Ce qui suit par exemple est beaucoup plus clair.
Jake a salué Bill. Jake n'aimait pas Bill alors il se tourna et partit dans l'autre sens.
Dans ce cas, être plus spécifique a rendu la phrase plus claire. Mais ce ne sera pas toujours le cas. Dans certains cas, être spécifique rend la lecture plus difficile.
Bill aime les livres, alors Bill est allé à la bibliothèque et Bill a sorti un livre que Bill a toujours aimé.
Dans ce cas, il serait plus facile de lire la phrase si nous utilisions "il" et, dans certains cas, omettions son nom, ce qui revient à utiliser le mot clé var
.
Bill aime les livres, alors il est allé à la bibliothèque et a sorti un livre qu'il a toujours aimé.
Ces exemples couvrent le Gist, mais ils ne racontent pas toute l'histoire. Dans ces exemples, il n'y avait qu'une seule façon de se référer à la personne. Soit en utilisant leur nom ou en utilisant un terme plus général comme "il" et "lui".
Dans le cas du code, nous avons 3 façons d’aider à ajouter de la clarté. Le type, le nom de la variable et l'affectation. Prenons cette ligne de code par exemple:
Person p = GetPerson();
La question est maintenant de savoir s'il y a suffisamment d'informations dans cette ligne de code pour vous aider à comprendre ce qui se passe.
Qu'en est-il de la ligne de code suivante? Voulez-vous toujours savoir ce que p
signifie dans ce cas:
var p = GetPerson();
Et maintenant:
var p = Get();
Ou maintenant:
var person = Get();
Ou celui-ci:
var t = GetPerson();
Ou ca:
var u = Person.Get();
Que le mot clé var
fonctionne dans un scénario donné dépend beaucoup du contexte du code, comme le nom des variables, des classes et des méthodes. Cela dépend également de la complexité du code et du reste du code qui l’entoure.
Personnellement, j'aime bien utiliser le mot clé var
qui est plus complet pour moi la plupart du temps. Mais j'ai aussi tendance à nommer mes variables d'après le type afin de ne perdre aucune information.
Cela dit, parfois, en fonction du contexte, je fais des exceptions, la nature de tout ce qui est complexe est complexe et les logiciels sont tout simplement complexes.
Je n'aimais pas ça aussi.
Je ne veux pas que cela se transforme en un débat sur l'utilisation de var
, il a ses utilisations mais ne devrait pas être utilisé partout.
Le point clé à retenir est que ReSharper est configuré selon les normes de codage de votre choix.
Edit: ReSharper et var
Ma règle est la suivante:
Déclarez-vous un type primitif (c.-à-d. byte
, char
, string
, int[]
, double?
, decimal
, etc.)? -> Utilisez le type:
string myStr = "foo";
int[] myIntArray = [123, 456, 789];
double? myDouble = 123.3;
Êtes-vous en train de déclarer un type complexe (c'est-à-dire List<T>
, Dictionary<T, T>
, MyObj
)? -> Utilisez var
:
var myList = List<string>();
var myDictionary = Dictionary<string, string>();
var myObjInstance = new MyObj();
Je vois beaucoup de réponses correctes, mais il manque la réponse complète.
Il est vrai que Resharper utilise abusivement var par défaut. Je pense que la plupart des gens seraient d'accord avec cela. Il est également plus facile de lire lorsque var est utilisé et le type est évident, par exemple lorsque vous utilisez une nouvelle instruction. J'ai vu un article qui montrait comment mettre à jour la gravité de l'inspection pour ne montrer que des astuces d'utilisation de var.
J'avais d'abord essayé de commenter d'autres publications pour préciser où les définir, mais je n'en avais pas la réputation. Apparemment, je n'ai pas non plus la réputation de publier ma capture d'écran des paramètres.
J'aurai expliquer comment y arriver.
Dans Visual Studio -> Menu principal -> Resharper -> Options -> Édition de code -> C # -> Style de code -> Utilisation des variables dans les déclarations
Je voudrais juste préciser que l'utilisation de "var" est recommandée dans les Conventions de codage C # "lorsque le type de la variable est évident à partir du côté droit de l'affectation, ou lorsque le type précis n’est pas important ", c’est probablement pour cette raison que la pointe est activée par défaut dans ReSharper. Ils fournissent également des cas où cela n’améliorerait pas la lisibilité ci-dessous dans le même document.
ReSharper recommande var car il a tendance à réduire la création d’objets.
Comparez ces deux exemples:
StringBuilder bld = new StringBuilder();
var bld = new StringBuilder();
C'est juste un raccourci censé être plus facile à lire.
je pense que c'est bien quand vous créez explicitement de nouveaux objets avec "nouveau". Cependant, dans votre exemple, il pourrait ne pas être évident si les classes n'étaient pas nommées correctement.
BTW, ReSharper établit une distinction entre "vous pouvez appliquer cette suggestion à votre code" et "votre code est cassé, vous voulez que je le répare?". Le mot clé var
se trouve dans la catégorie des suggestions, avec des éléments tels que "inverser si pour réduire l'imbrication"; vous n'êtes pas obligé de le suivre.
Vous pouvez configurer le niveau d'ennui de chacune de ses alertes via la boîte de dialogue Options ou directement via le menu contextuel de cette alerte. Vous pouvez rétrograder des éléments tels que la suggestion var
afin qu'ils soient moins présents, ou vous pouvez mettre à niveau des éléments tels que l'alerte 'utiliser une méthode d'extension' afin qu'elle s'affiche comme une erreur réelle.
La fonctionnalité var
de .Net 3.0 est juste inférence de type , ce qui est sûr et qui rend souvent votre code plus facile à lire. Mais vous n’êtes pas obligé et pouvez désactiver cette recommandation si vous le souhaitez.
Le var est incroyable! J'ai rencontré de nombreux développeurs qui ont l'impression que var
est lié à un type dynamique, ce n'est pas le cas. Il est toujours typé statiquement, c'est le compilateur qui le décide.
Voici quelques points positifs étonnants liés à l'utilisation de var
Moins de frappe var est plus court et plus facile à lire, par exempleDictionary<int,IList<string>> postcodes = new Dictionary<int,IList<string>>()
Yuk.var postcodes = new Dictionary<int,IList<string>>()
\o/\ o /
Noms de variables plus descriptifs - ténus, mais je pense qu’il est important de laisser ici la nature fluide de var
. Comme var
est un peu vague, cela encourage vraiment un nom de variable plus descriptif plutôt que de laisser le type parler pour lui-même.
Moins de changements de code - si le type de retour d'un appel de méthode change. Il vous suffit de modifier l’appel de méthode, pas à chaque emplacement utilisé.
Types anonymes - Les types anonymes sont un concept très puissant, en particulier dans des domaines tels que WebApi ressources partielles . Sans var, ils ne peuvent pas être utilisés.
Parfois cependant, il est utile de déclarer explicitement les types et je trouve cela le plus utile dans les primitives ou les structs. Par exemple, je ne trouve pas personnellement cette syntaxe très utile:
for(var i = 0; i < 10; i++)
{
}
contre
for(int i = 0; i < 10; i++)
{
}
Tout dépend de vos préférences personnelles, mais utiliser var
accélérera vraiment votre développement et vous permettra de débloquer tout un monde de bonnes choses de type anonyme.
Le mot clé var
a été introduit dans C # 3.0 - il nous permet d'oublier de spécifier explicitement notre type.
Il n'y a pas de réelle différence selon que vous utilisez ou non
MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
ou
var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);
sauf la lisibilité pure et moins de chance d'erreur.
Cela ressemble à un exemple cliché, mais supposons que ce qui suit puisse vous aider à comprendre:
var myInt = 23;
renvoie un type int
, alors que
var myInt = "23";
renvoie un type string
.
Spécifier un type d'objet explicite est en quelque sorte redondant. Même traduit en anglais, cela semble redondant: "mettre un objet de type X dans une variable de type X" vs "Mettre un objet de type X dans une variable".
Cependant, l'utilisation de 'var' a ses limitations. Il empêche l'utilisation ci-dessous de polymorphisme qui est beauté pure:
Supposons qu'un chien étend Animal; Cat étend la hiérarchie des classes d'animaux:
Animal x = new Dog();
DoStuffWithDog(x as Dog);
x = new Cat();
DoStuffWithCat(x as Cat);
void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}
Le même code, avec x déclaré avec 'var' ne compilera pas.
var x = new Dog(); // from this point, x is a Dog
DoStuffWithDog(x as Dog);
x = new Cat(); // cannot assign a Cat instance to a Dog
DoStuffWithCat(x as Cat);
void DoStuffWithDog(Dog d){}
void DoStuffWithCat(Cat c){}
Quoi qu'il en soit, revenons à la question initiale, je n'utilise pas Resharper, mais je suppose que c'est suffisamment intelligent pour détecter le moment où il ne faut pas utiliser 'var'. :-)
À mon avis, var
ne devrait être utilisé que lorsque le type est clairement défini lors de la définition de la valeur de la variable.
Exemple:
var s = "string value";
Il est évident que s
est un string
.
Je pense que cela convient également lorsque le nom du type de variable est très complexe.
Exemple:
Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>> dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();
// This is a little easier to read than the above statement
var dict = new Dictionary<SomeCustomKeyType, Dictionary<AnotherCustomKeyType, List<int>>>();
À part ces scénarios, je ne vois pas de GAIN à utiliser avec var
, mais je peux penser à certains scénarios dans lesquels cela peut être préjudiciable:
Par exemple, un type jetable dont la valeur de la variable de droite ne l’indique pas clairement. On peut facilement oublier la disposition de l’Isposable
Exemple:
// returns some file writer
var wr = GetWriter();
wr.add("stuff");
wr.add("more stuff");
//...
//...
// Now `wr` needs to be disposed,
// but there is no clear indication of the type of `wr`,
// so it will be easily overlooked by code writer and code reviewer.
Il n'y a pas de différence technique, si vous utilisez var, le type est impliqué par le compilateur. Si vous avez un code comme celui-ci:
var x = 1;
x est supposé être un int et aucune autre valeur ne peut lui être assignée.
Le mot clé var est utile si vous changez le type de la variable. il vous suffit alors de faire un changement au lieu de deux:
var x = 1; --> var x = "hello";
int x = 1; --> string x = "hello";
Pour ceux qui n'aiment pas l'utilisation constante de "var":
REMARQUE: vous pouvez également empêcher le resharper de passer par défaut à var en faisant "introduction de variable". C’était quelque chose qui m’avait frustré pendant longtemps, c’était toujours défaut, et je le changeais à chaque fois.
Ces paramètres sont sous Édition de code -> C # -> Style de code
'var' ajoute une sorte d'élément "dynamique" à votre code (bien que le code reste bien sûr strictement typé). Je déconseille de l'utiliser dans les cas où le type n'est pas clair. Considérons cet exemple:
var bar = GetTheObjectFromDatabase();
bar.DoSomething();
ClassA {
void DoSomething() {
//does something
}
}
ClassB {
void DoSomething() {
//does something entirely different
}
}
Si le type de retour de GetTheObjectFromDatabase () est modifié de type A à B, nous ne le remarquerons pas, car les deux classes implémentent DoSomething (). Cependant, le code peut maintenant réellement faire quelque chose de complètement différent.
Cela peut être aussi subtil que d'écrire différentes choses dans un journal, de sorte que vous pourriez ne pas remarquer qu'il est trop tard.
L’utilisation suivante de var devrait toujours être correcte:
var abc = new Something();
Il n'y a pas de différence technique (comme l'a souligné eWolf). Vous pouvez utiliser l’un ou l’autre, le code CLR généré sera identique.
À mon avis, le principal avantage est que cela tend à vous obliger à utiliser une meilleure dénomination des variables. Dans votre exemple, "foo" est un très mauvais choix pour un nom de variable.
Selon JetBrains (l'auteur de ReSharper), ils encouragent l'utilisation de var par défaut.
De leur site web :
L'utilisation de variables locales implicitement typées (également appelé mot-clé var) introduites en C # 3.0 est devenue très populaire en raison de l'amélioration de la lisibilité du code résultant. Par défaut, ReSharper encourage également l'utilisation du mot-clé var, mais les préférences de son utilisation sont configurables de manière flexible. Par exemple, vous pouvez choisir d'utiliser des types explicites dans des cas spécifiques ou partout.