web-dev-qa-db-fra.com

Pourquoi ReSharper veut-il utiliser 'var' pour tout?

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.

203
Chris

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>();
181
Mark Sherretta

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);
281
Guffa

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.

95
Bryan Menard

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.

67
John K

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:

ReSharper Options Menu

Ensuite, sous "Inspection du code" en ajustant la "Gravité de l'inspection" de la langue de votre choix, dans mon cas c #:

Turn off implicitly typed local variable suggestion

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 :)

38
Erikest

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.

23
Philipp

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

23
Luis Perez

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

17
LiamB

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();
    
13
Sumner Evans

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

  • Pour les types intégrés Utiliser un type explicite
  • Pour les types simples, utilisez 'var' lorsque évident
  • Ailleurs Use'var '

enter image description here

12
Nathan Kovac

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.

12
jose

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.

6
Paul Sasik

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.

6
Tim Robinson

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.

5

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 exemple

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

3
KnowHoper

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.

référence MSDN

2
Daniel May

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'. :-)

2
xtrem

À 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.
2
James Wierzba

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";
2
eWolf

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

enter image description here

1
Derek

'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();
1
lolaldanee

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.

0
Jaco Pretorius

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.

0
Jeff Reddy