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


214

Je viens de commencer à utiliser ReSharper avec Visual Studio (après les nombreuses recommandations sur SO). Pour l'essayer, j'ai ouvert un récent projet ASP.NET MVC. L'une des premières et des plus fréquentes choses que j'ai remarquées suggérer est de changer la plupart / toutes mes déclarations explicites à la varplace. 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 suis pas issu de l'informatique ou du domaine .NET, étant récemment tombé dans le développement .NET, j'aimerais vraiment comprendre ce qui se passe et savoir si cela présente des avantages ou non.



27
J'y pense depuis un moment et je suis arrivé à la conclusion que je devrais toujours l'utiliser var, même lorsque le type n'est pas évident du tout! la raison est parce qu'il oblige - moi à choisir le nom le plus descriptif que je peux trouver et , finalement , qui rend le code beaucoup, beaucoup plus facile à lire. En fin de compte, cela aide également à séparer la logique de la mise en œuvre. Bien sûr, c'est juste mon opinion, j'espère que cela aiderait quelqu'un;).
MasterMastic

Réponses:


189

L'une des raisons est une meilleure lisibilité. Ce qui est mieux?

Dictionary<int, MyLongNamedObject> dictionary = new Dictionary<int, MyLongNamedObject>();

ou

var dictionary = new Dictionary<int, MyLongNamedObject>();

260
Je dirais le premier. Plus facile à voir ce qui se passe!
Mongus Pong

104
Champignon: Aimez-vous Aimez-vous Redundant Text Redundant Text? : D
Mark Simpson

73
Être explicite est plus clair à mon avis. L'utilisation excessive de var crée un mal de tête dans certains scénarios.
user1231231412

172
Je déteste quand les développeurs utilisent varpour tout - je fais beaucoup et revues de code en utilisant TFS (Les diffs basés sur le Web) et il rend mon travail extrêmement difficile: par exemple var items = GetSomeItems();vs IDataReader dr = GetSomeItems();manquantes à l' aide déclaration sur moi à la fois , mais plus facile pour attraper lors de l' utilisation IDataReadervs var.
Chris Gessler

17
si vous êtes un bon développeur qui écrit du bon code et que vous utilisez une bibliothèque comme Resharper, vous n'avez pas besoin de connaître le type explicite avec lequel vous traitez. Tout comme lorsque vous utilisez des interfaces pour déclarer un contrat, mais pas une classe concrète, var vous permet de dire que vous ne vous souciez pas du "type" de retour, vous ne vous souciez que de ce qu'il fait et en utilisant des variables bien nommées, le long avec les assistants intelli-sense et resharper / VS (tels que CTRL + CLIC pour naviguer vers la définition), vous obtiendrez 99% du chemin. De plus, l'utilisation de var signifie que je n'ai pas à réécrire ma base de code si je change un type de retour de méthode.
Joshua Barker

286

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

36
Pour jouer à Devils Advocate, peut-être que si le type n'est pas clair à partir de la méthode ou du nom de la variable, cela indique un problème de nommage plus qu'une utilisation excessive de var. Je suis d'accord en principe cependant, var ne doit être utilisé que s'il ne supprime pas la clarté.
Matt Briggs

33
Dans ce cas, je préfère utiliser de meilleurs noms de variables. Vous proposez essentiellement que nous regardions pour voir où la variable est définie pour comprendre le type - je propose que nous nommions mieux les variables afin de connaître le but de la variable.
Jaco Pretorius

18
@Jaco: +1, mais il convient de mentionner que les informations sur le type ne sont pas recommandées pour être dans un nom de variable. Par exemple, la notation hongroise n'est pas considérée comme une bonne pratique.
Roman Boiko

8
La question de savoir si les paramètres par défaut de ReSharper sont une utilisation excessive varest une question d'opinion, et non "clairement" une chose ou une autre. Je préfère ne pas taper des choses que le compilateur peut comprendre par lui-même. J'aime l'inférence de type C # et souhaite souvent qu'elle soit aussi bonne que l'inférence de type F #. Si je le pouvais, je laisserais de côté les types explicites des paramètres de méthode et les types de retour, comme c'est la norme en F #. Bien sûr, tout le monde n'est pas d'accord.
Joel Mueller

15
@AnonymousType: Vous manquez toujours le point. Vous avez dit que les noms de méthode devraient toujours refléter l'intention de la méthode, mais même s'ils le font, cela ne signifie pas que le nom spécifie le type de la valeur de retour. La méthode de lecture d'un Streamobjet par exemple est nommée Read, non ReadAndReturnNumberOfBytesAsInt32.
Guffa

99

Personnellement, je préfère désactiver cette suggestion. L'utilisation varpeut 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 varet quand je ne le fais pas. Mais encore une fois, c'est juste moi.


11
Je pensais que ReSharper était censé être assez intelligent; Cela ne devrait-il pas être assez intelligent pour savoir quand le type résultant est évident (par exemple quelque chose avec le nouveau mot-clé) et quand il n'est pas évident?
DisgruntledGoat

3
Eh bien, je ne connais pas les particularités de la fonctionnalité, mais je sais que j'ai été submergé par la quantité de suggestions qu'elle a faites; Et j'utilise varassez souvent aussi.
Bryan Menard,

5
J'ai découvert que lorsque vous utilisez toujours var (comme le suggère resharper), cela vous oblige à nommer correctement vos variables.
Sauleil

Pouvez-vous désactiver la suggestion?
Chris S

@AngeDeLaMort: le fait est que cela vous oblige à utiliser des noms qui sont incorrects, par exemple var methodXYResultIntArray. C'est contre toutes les normes de codage et moins concis que int[] methodXYResult. Si vous souhaitez renvoyer un byte[]de la méthode à l'avenir, tous vos noms de variables sont faux. Avec des types explicites, vous pouvez refactoriser cela très facilement. Il y a des raisons d'utiliser var, par exemple avec un Dictionary<string, List<SomeType<int>>>. Mais si le nom de type complet n'est pas trop long et que vous n'utilisez pas newdu côté droit (ou une distribution explicite), le resharper ne devrait pas le suggérer.
Tim Schmelter

69

varpeut augmenter la lisibilité du code tout en diminuant la compréhension immédiate du code. De même, 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 augmentent ou diminuent ensemble.

Le facteur est de savoir à quoi varest appliqué et dans quelle mesure la cible prend en charge l'obfuscation immédiate de son type de données au lecteur, ou si ses informations de type sont nécessaires pour comprendre la partie de programme à portée de main.

Par exemple, une mauvaise dénomination peut entraîner varune diminution de la compréhension du code. Ce n'est cependant pas varla faute:

var value1 = GetNotObviousValue(); //What's the data type? 
//vs. 
var value2 = Math.Abs(-3); // Obviously a numeric data type. 

Parfois, cela n'a pas de sens d'utiliser vardes 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, il varpeut être utile de 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 varquand un type anonyme est présent car il n'y a pas de nom de type pour l'appeler par:

var o = new { Num=3, Name="" };

Malgré que Visual Studio Intellisense fournisse des informations de type malgré var, vous devez alors vous fier moins à 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é, sur la base des exemples ci-dessus, je suggérerais que l'application de la carte blanche varn'est pas une bonne idée car la plupart des choses sont à faire avec modération et en fonction des circonstances, comme indiqué ici.

Pourquoi Resharper l'utilise-t-il partout par défaut? Je suggérerais pour plus de facilité, car il ne peut pas analyser les nuances des situations pour décider du meilleur moment pour ne pas l'utiliser.


5
À mon humble avis, vos exemples sont en fait de bonnes raisons d'utiliser var, cela vous obligera à écrire des noms de méthode décents. GetNumber() -but what type?- eh bien, pourquoi vous en souciez-vous? Si c'est si important de savoir, appelez la méthode GetNumberAsDouble(), alors c'est aussi clair et cela fonctionnera si vous avez une méthode qui revient stringet une qui revient double.
nicodemus13

10
@ nicodemus13 Vous savez généralement quand vous vous souciez du type de retour d'une fonction lorsque vous utilisez réellement la valeur de retour plutôt que lorsque vous écrivez la fonction elle-même. Votre schéma de dénomination suggéré pourrait conduire à des abus comme GetResultsAsIEnumerableOfDouble et tout ce qu'il fait est de déplacer les informations de type que vous avez supprimées du côté gauche d'une affectation en utilisant var vers la droite de l'affectation.
Eric

var value2 = Math.Abs ​​(-3); // Evidemment un type de données numérique. Désolé, je suis en désaccord sur celui-ci, complètement, étant donné que la méthode Abs a 7 surcharges qui ne mènent à rien d'autre que de l'obscurité quand on la regarde, imo
s1cart3r

var peut également conduire à des erreurs logiques subtiles comme: var counter = "0"; quand ce que vous voulez est un entier.
alaniane

42

Dans ReSharper (8.02, mais probablement dans d'autres versions), l'option pour la suggestion "Utiliser la déclaration de variable locale implicitement typée" peut être ajustée selon vos préférences , quelle qu'elle soit, en ouvrant d'abord le menu d'options pour ReSharper:

Menu Options ReSharper

Ensuite, sous "Code Inspection" en ajustant la "gravité de l'inspection" de la langue que vous avez choisie, dans mon cas c #:

Désactiver la suggestion de variable locale typée implicitement

Comme vous pouvez le voir, il existe des options pour ajuster toutes les suggestions de ReSharper. J'espère que cela aide quelqu'un comme moi qui a déjà une stratégie d'utilisation 'var' et veut juste que ReSharper la respecte :)


Cela répond à une question différente qui n'a pas été posée du tout.
Carles Alcolea

9
Mais c'est pertinent pour beaucoup de ceux qui le recherchent en arrivant ici. +1
Ori Nachum

24

Je suis surpris que personne n'ait mentionné qu'il est également plus facile de changer le type de l'objet instancié, car

AVeryLongTypeName myVariable = new AVeryLongTypeName( arguments );

est une forme de répétition . Si je veux changer AVeryLongTypeNamedans l'une de ses classes dérivées, je n'ai besoin de changer cela qu'une seule fois lors de l'utilisation varet je peux toujours accéder aux méthodes des classes enfants.

En dehors de cela, la lisibilité améliorée est un point important, mais comme d'autres l'ont dit, var ne devrait pas être surutilisé, donc je pense que désactiver l'indication dans Resharper est absolument correct.


Très utile pour appeler des méthodes d'usine plutôt que "nouvelles"
Ian Ringrose

Si vous devez utiliser «MyClass» lorsque vous écrivez initialement le code et que cela fonctionne, alors cela fonctionne. Lorsque vous devez le changer, vous devez aller le changer partout, surtout lorsque vous avez des interfaces impliquées. Le code ne doit pas être traité comme un essai, il doit être sémantique et bien défini.
Piotr Kula

24

'var' signifie être clair

Le principal débat sur l'utilisation varou non du mot - clé concerne la lisibilité du code pour vous et les autres développeurs.

Tout comme si vous écriviez une histoire, il n'y a pas de bonne réponse définitive. Mais regardons quelques exemples de cela en anglais simple.

Jake a dit bonjour à Bill. Il ne l'aimait pas, alors il s'est retourné et est allé 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 «il» et «lui», c'est comme utiliser le varmot - clé. Dans ce cas, il peut être utile d'être plus précis. Par exemple, ce qui suit est beaucoup plus clair.

Jake a dit bonjour à Bill. Jake n'aimait pas Bill alors il se tourna et partit dans l'autre sens.

Dans ce cas, être plus précis 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 utilisons "il" et dans certains cas, omettons son nom tous ensemble, ce qui équivaut à utiliser le varmot - clé.

Bill aime les livres, alors il est allé à la bibliothèque et a sorti un livre qu'il a toujours aimé.

Ces exemples couvrent l'essentiel, 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, soit 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. Prenez cette ligne de code par exemple:

Person p = GetPerson();

La question devient maintenant: y a-t-il 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? Souhaitez-vous encore savoir ce que psignifie 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();

Le fonctionnement du mot clé vardans un scénario donné dépend en grande partie du contexte du code, comme la façon dont les variables, les classes et les méthodes sont nommées. Cela dépend également de la complexité du code et du reste du code qui l'entoure.

Personnellement, j'aime utiliser le varmot - clé qui est le plus complet pour moi la plupart du temps. Mais j'ai aussi tendance à nommer mes variables après le type, donc je ne perds vraiment aucune information.

Cela dit, parfois, selon le contexte, je fais des exceptions, telle est la nature de tout ce qui est complexe, et le logiciel n'est rien sinon complexe.


1
J'aime le mieux cette réponse, car je n'ai rien contre vartant que je sais ce que c'est en lisant cette seule ligne. Si je n'ai aucune idée de ce qu'une méthode d'une autre solution utilisant un modèle de domaine différent renvoie, je préfère que ce type soit défini explicitement, ce qui le rend beaucoup plus facile à lire. +1
Piotr Kula

Dans tous vos cas où le type retourné n'est pas évident, je suis d'accord que vous ne devez pas utiliser var car vous omettez maintenant des informations utiles.
roule

18

Je n'aimais pas cela non plus.

Je ne veux pas que cela se transforme en débat sur l'utilisation de var, il a ses utilisations mais ne devrait pas être utilisé partout.

La chose clé à retenir est que ReSharper est configuré selon les normes de codage que vous souhaitez.

Edit: ReSharper et var


13
Après environ un an de résistance, j'utilise presque toujours var maintenant.
LiamB

15

Je vois beaucoup de bonnes réponses, mais je manque la réponse complète.

Il est vrai que ReSharper sur-utilise varpar défaut. Je pense que la plupart des gens seraient d'accord avec cela. Il est également plus facile de lire quand varest utilisé et le type est évident, comme lorsque vous utilisez une newinstruction. J'ai vu un article qui montrait comment mettre à jour la gravité de l'inspection pour n'afficher que des conseils d'utilisation var.

J'avais d'abord essayé de commenter d'autres articles pour ajouter où les placer, mais je n'avais pas la réputation pour cela. Apparemment, je n'avais pas non plus la réputation de publier ma capture d'écran des paramètres.

Je vais vous expliquer comment y arriver.

Dans Visual Studio> Menu principal> Resharper> Options> Édition de code> C #> Style de code> Var utilisation dans les déclarations

  • Pour les types intégrés Utilisez un type explicite
  • Pour les types simples Utilisez 'var' lorsque cela est évident
  • Utiliser ailleurs «var»

entrez la description de l'image ici

Documentation d'aide ReSharper: Style de syntaxe de code: Typage implicite / explicite (mot-clé 'var') - Configurer les préférences d'utilisation du mot-clé 'var'


Cela devrait être marqué comme la bonne réponse en dehors des différents débats, c'est l'approche équilibrée
Brian Ogden

Pourriez-vous donner un exemple sur la façon dont "où évident" est décidé?
roule


13

Ma règle est la suivante:

  • Est -ce que vous déclarez un type primitif (c. -à byte, char, string, int[], double?, decimal, etc.)? -> Utilisez le type:

    string myStr = "foo";
    int[] myIntArray = [123, 456, 789];
    double? myDouble = 123.3;
  • Déclarez-vous un type complexe (c. List<T>-à- d . Dictionary<T, T>, MyObj)? -> Utilisation var:

    var myList = List<string>();
    var myDictionary = Dictionary<string, string>();
    var myObjInstance = new MyObj();

Je ne suis pas d'accord, string myStr = "foo";c'est évident que c'est une chaîne. Je mettrais tous vos exemples dans l'utilisation de la catégorie var ... et les déclarations qui sont des retours d'une méthode pour utiliser le type explicité. Mais à la fin de la journée, c'est tout ce que vous et votre équipe pensez être le mieux pour le projet particulier.
Dean Meehan

12

Je voudrais juste souligner que l'utilisation de "var" est recommandée dans les conventions de codage C #

lorsque le type de la variable est évident du côté droit de l'affectation, ou lorsque le type précis n'est pas important

c'est probablement la raison pour laquelle l'astuce est activée par défaut dans ReSharper. Ils fournissent également certains cas où cela n'améliorerait pas la lisibilité juste en dessous dans le même document.


C'est génial lorsque vous savez que le type vient de System.Diagnostics.PerformanceCounter() - Vous pouvez facilement dire son compteur de performances à partir de la classe de diagnostic intégrée. Mais quel type est retourné ici? var thingyMaBob = GetThatSpecialThing(18,null,(MyEnum)2)? Aucun indice de synchronisation, surtout si vous avez bien plus de 100 projets dans votre solution.
Piotr Kula

"Recommandé lorsque le type de la variable est évident" et "Ils fournissent également des cas où cela n'améliorerait pas la lisibilité juste en dessous dans le même document". Honnêtement, je pense que j'ai raté votre argument. Ma réponse dit la même chose que vous dites.
jose

6

ReSharper recommande varcar il a tendance à désencombrer la création d'objets.

Comparez ces deux exemples:

StringBuilder bld = new StringBuilder();

var bld = new StringBuilder();

C'est juste un raccourci qui est censé être plus facile à lire.

Je pense que c'est bien quand vous créez explicitement de nouveaux objets avec "nouveau". Dans votre exemple cependant, il peut ne pas être évident si les classes n'ont pas été nommées correctement.


6

BTW, ReSharper fait une distinction entre «vous voudrez peut-être appliquer cette suggestion à votre code» et «votre code est cassé, voulez-vous que je le répare?». Le varmot-clé se trouve dans la catégorie de suggestion, avec des éléments comme "inverser si pour réduire l'imbrication"; vous n'êtes pas obligé de le suivre.

Vous pouvez configurer la gêne 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 choses comme la varsuggestion afin qu'elles soient moins importantes, ou vous pouvez mettre à niveau des choses comme l'alerte `` utiliser la méthode d'extension '' pour qu'elle apparaisse comme une erreur réelle.


5

La varfonctionnalité de .Net 3.0 est juste une inférence de type , qui est sûre de type et rend souvent votre code plus facile à lire. Mais vous n'êtes pas obligé de le faire et pouvez désactiver cette recommandation dans Resharper si vous le souhaitez.


4

Le Var est incroyable! J'ai rencontré beaucoup de développeurs qui ont l'impression d' varêtre liés à un type dynamique, ce n'est pas le cas. Il est toujours typé statiquement, c'est juste décidé par le compilateur.

Voici quelques avantages étonnants de l'utilisation de var

Moins de 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 varbriller ici la nature fluide de la variable . Comme varc'est un peu vague, cela encourage vraiment un nom de variable plus descriptif plutôt que de laisser le type parler de lui-même.

Moins de changements de code - si le type de retour d'un appel de méthode change. Vous n'avez qu'à changer l'appel de méthode, pas tous les endroits où il est utilisé.

Types anonymes - les types anonymes sont un concept vraiment puissant, en particulier dans des domaines tels que les ressources partielles WebApi . Sans var, ils ne peuvent pas être utilisés.

Parfois, cependant, il est utile de déclarer explicitement des types et je trouve cela très utile dans les primitives ou les structures. 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 vardépend des préférences personnelles, mais l'utilisation accélérera vraiment votre développement et débloquera tout un monde de bonté de type anonyme.


2

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 implicitement un entier et aucune autre valeur ne peut lui être affecté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";

1
@AlexKamburov le code 10 lignes ci-dessous se cassera de toute façon, n'est pas lié à var.
user3285954

1
@ user3285954 Dans certains cas, var peut masquer le problème et c'est là que les choses peuvent devenir laides. Le problème n'est pas dans l'écriture de code, le problème est dans la maintenabilité. Certains soutiennent que c'est plus propre avec var mais je le vois parfois comme de l'obscurcissement. C'est proche d'un débat religieux. brad-smith.info/blog/archives/336 Personnellement , j'utilise var uniquement pour les instructions Linq et d'autres endroits où déclarer le type est vraiment bavard. Je pense que var est un bon ajout et les gens doivent regarder les commentaires d'Anders Hejlsberg sur les raisons de son introduction.
Alex Kamburov

2

Le varmot clé 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 si vous utilisez

MyObject foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

ou

var foo = DB.MyObjects.SingleOrDefault(w => w.Id == 1);

sauf lisibilité pure et moins de risque d'erreur.

Cela semble être un exemple cliché, mais dites que ce qui suit peut vous aider à comprendre:

var myInt = 23;

renvoie un inttype, alors que

var myInt = "23";

renvoie un stringtype.

Référence MSDN


2

La spécification d'un type d'objet explicite est en quelque sorte redondante. 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 limites . Il empêche l'utilisation ci-dessous du polymorphisme qui est pure beauté :

Supposons qu'un chien étend un animal; Cat étend la hiérarchie des classes animales:

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 sera pas compilé .

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 d'origine, je n'utilise pas Resharper, mais je suppose que c'est assez intelligent pour détecter quand ne pas utiliser 'var'. :-)


4
Le casting inutile (avec as) est vraiment affreux. Vous transformez les erreurs de compilation en erreurs d'exécution si vous avez quelque chose comme Animal x = new Cat(); DoStuffWithDog(x as Dog); Pourquoi réutiliser x? Chien x = nouveau chien (), chat y = nouveau chat (), boom plus d'ambiguïté possible.
Mark Sowul

la conversion (avec 'as' ou non) peut entraîner une erreur d'exécution. Qu'est-ce qui est si «horrible» dans le casting quand vous savez ce que vous faites? Pourquoi réutiliser x? L'exemple ici est illustratif. Le but de l'exemple est de montrer comment l'utilisation de «var» peut entraîner des limitations lorsqu'une référence est censée être polymorphe.
xtrem

5
Non, ce n'est pas possible: le polymorphisme est l'opposé de ce qui se passe ici. Cela essaie de passer des objets de type Animaldans des méthodes qui prennent Doget Cat. Polymorphisme est l'inverse: pour que vous puissiez passer des objets de type Doget Catdans une méthode qui prend Animal, par exemple void Walk(Animal a): Walk(new Cat()),Walk(new Dog())
Mark Sowul

Vous ne devriez pas réutiliser les variables de cette façon, cela conduit à des bugs très désagréables. Pas si évident dans les méthodes courtes mais quand vous avez 15-20 lignes de code, vous oublierez ce qu'est x. Ne soyez pas paresseux: var dog = new Dog (); DoStuff (chien); var cat = new Cat (); DoStuff (chat);
user3285954

2
Pas de bagarre. Je n'ai pas de sentiments pour les deux façons de déclarer des variables (implicites ou explicites). J'utilise en fait au moins un de chaque jour. Je souligne simplement que lorsque vous avez choisi la méthode implicite (var), le compilateur décidera du type le plus étroit possible pour vous. Ce qui n'est peut-être pas toujours ce que vous voulez. C'est tout.
xtrem

2

À mon avis, varne devrait être utilisé que lorsqu'il est immédiatement clair quel est le type lors de la définition de la valeur de la variable.

Exemple:

var s = "string value";

Il est évident que sc'est un string.

Je pense qu'il est également approprié 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 aucun gain à faire en utilisant 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 n'affiche pas clairement le type. L'élimination de l'IDisposable peut facilement être oubliée

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.

1

'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érez 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 () passe du type A au type B, nous ne le remarquerons pas, car les deux classes implémentent DoSomething (). Cependant, le code peut maintenant faire quelque chose de complètement différent.

Cela peut être aussi subtil que d'écrire des choses différentes dans un journal, donc vous ne remarquerez peut-être pas qu'il est trop tard.

L'utilisation suivante de var devrait toujours convenir:

var abc = new Something();

1

Pour ceux qui n'aiment pas l'utilisation constante de "var", vous pouvez également empêcher ReSharper de passer par défaut à var lors de l'introduction de "variable". C'est quelque chose qui m'a frustré pendant longtemps, il était toujours par défaut var et je le changeais à chaque fois.

Ces paramètres sont sous Édition de code> C #> Style de code

entrez la description de l'image ici


0

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 vous oblige à utiliser une meilleure dénomination des variables. Dans votre exemple, 'foo' est un assez mauvais choix pour un nom de variable.


0

Selon JetBrains (l'auteur de ReSharper), ils encouragent l'utilisation de var par défaut.

Depuis leur site Web :

L'utilisation de variables locales implicitement typées (également appelées varmots-clés) introduites dans C # 3.0 est devenue très populaire car elle améliore la lisibilité dans de nombreux scénarios. Par défaut, ReSharper encourage également l'utilisation du varmot-clé, mais les préférences de son utilisation sont configurables de manière flexible - par exemple, vous pouvez opter pour l'utilisation de types explicites dans des cas spécifiques ou partout et ReSharper vous aidera à appliquer vos préférences.


Où puis-je configurer quand exiger une déclaration de type explicite?
user764754
En utilisant notre site, vous reconnaissez avoir lu et compris notre politique liée aux cookies et notre politique de confidentialité.
Licensed under cc by-sa 3.0 with attribution required.