Que faut-il utiliser: var ou type de nom d'objet? [dupliquer]

cette question a déjà une réponse ici:

c'est une question que lors de la programmation je me demande toujours: ce qu'il faut utiliser lorsque nous écrivons code:

var myFiles = Directory.GetFiles(fullPath);

ou

string[] myFiles = Directory.GetFiles(fullPath);

var est nouveau et est un variables locales implicitement dactylographiées , de sorte que nous ne pouvons utiliser localement et il a des règles comme ne peut pas être null, etc. mais je me demande si nous avons tout avantage de l'utiliser "normalement".

la partie "normalement" dit, pas dans types anonymes , Initialisateurs D'objets et de collections et expressions de requête où que a l'intention d'utiliser le var objet anonyme, donc ce que je veux dire... tout comme l'exemple ci-dessus.

qu'en pensez-vous?

52
demandé sur Vikrant 2008-10-25 23:21:21

8 réponses

au-delà de l'utilisation évidente de var avec LINQ, Je l'utilise également pour abréger des déclarations variables poilues pour la lisibilité, par exemple:

var d = new Dictionary<string, Dictionary<string, Queue<SomeClass>>>();

en général, j'obtiens une sorte de confort (à défaut d'un meilleur mot) de la dactylographie statique qui me rend réticent à l'abandonner. J'aime le sentiment que je sais ce que je fais quand je déclare une variable. Déclarer une variable n'est pas seulement dire quelque chose au compilateur, c'est dire à la personne qui lit votre code quelque.

Laissez-moi vous donner un exemple. Supposons que j'ai une méthode qui retourne un List<string> . Ce code est certainement correct, et je pense que c'est comme ça que 90% des développeurs de C# l'écriraient probablement:

List<string> list = MyMethod();

évidemment, non? En fait, voici un endroit que vous pouvez tout aussi facilement utiliser var .

C'est assez vrai. Mais cette version du code n'est pas seulement déclarer une variable, il est me disant ce que la personne qui l'a écrit a l'intention de faire:

IEnumerable<string> list = MyMethod();

le développeur qui a écrit ce code me dit" Je ne vais pas changer cette liste, ni utiliser un index pour accéder à ses membres. Tout ce que je vais faire, c'est itérer à travers."C'est beaucoup d'informations à faire passer, en une seule ligne de code. C'est quelque chose que vous abandonnez si vous utilisez var .

bien sûr, vous n'êtes pas abandonner si vous n'utilisiez pas c'est en premier lieu. Si vous êtes le genre de développeur qui écrirait cette ligne de code, vous savez déjà que vous n'utiliseriez pas var là.

Edit:

je viens de relire le billet de Jon Skeet, et cette citation d'Eric Lippert me sautait dessus:

implicitement dactylographiés locaux sont juste une petite façon dans laquelle vous pouvez souligner le comment et donc mettre l'accent sur le quoi.

je pense qu'en fait, dans de nombreux cas, l'utilisation de la dactylographie implicite laisse le quoi implicite. C'est normal de ne pas s'attarder sur le quoi. Par exemple, je vais simplement écrire une requête de LINQ comme:

var rows = from DataRow r in parentRow.GetChildRows(myRelation)
           where r.Field<bool>("Flag")
           orderby r.Field<int>("SortKey")
           select r;

quand j'ai lu ce code, une des choses que je pense quand je le lis est rows est un IEnumerable<DataRow> ."Parce que je sais que ce que LINQ queries retour est IEnumerable<T> , et je peux voir le type de l'objet étant sélectionné à droite.

C'est un cas où le quoi n'a pas a été rendu explicite. Il a été laissé pour moi d'en déduire.

maintenant, dans environ 90% des cas où J'utilise LINQ, cela n'a pas d'importance. Parce que 90% du temps, la ligne suivante du code est:

foreach (DataRow r in rows)

mais il n'est pas difficile d'imaginer un code dans lequel il serait très utile de déclarer rows comme IEnumerable<DataRow> - code où beaucoup de différents types d'objets étaient interrogés, il n'était pas possible de mettre la déclaration de requête à côté de l'itération, et il serait utile de pouvoir inspecter rows avec IntelliSense. Et c'est une chose que, pas une chose.

61
répondu Robert Rossney 2008-10-25 21:21:44

vous obtiendrez une grande variété d'opinions sur celui - ci-DE" utiliser var partout "à" n'utiliser var avec des types anonymes, où vous avez essentiellement à."J'aime Eric Lippert est de prendre sur elle :

tout code est une abstraction. Est ce que le code est "vraiment" faire est manipuler des données? Aucun. Les numéros? Bits? Aucun. Les tensions? Aucun. Les électrons? Oui, mais comprendre le code au niveau de les électrons est une mauvaise idée! L'art de la le codage est de savoir ce que le droit le niveau d'abstraction est pour l' public.

dans une langue de haut niveau il y a toujours Cette tension entre ce que code fait (sémantiquement) et comment le le code l'accomplit. Entretien les programmeurs doivent comprendre à la fois le quoi et le comment, si ils vont pour réussir à faire des changements.

le point entier de LINQ est qu'il massivement dé-souligne le "comment" et massivement souligne le"quoi". Par en utilisant une compréhension de requête, le programmeur est à dire à l'avenir public "je crois que vous devriez ni savoir ni se soucier exactement comment cela de résultat est calculé, mais vous devrait se soucier beaucoup de ce que le la sémantique de l'ensemble." Ils rendent le code plus proche du processus opérationnel mis en œuvre et plus loin des bits et des électrons que faire aller.

implicitement dactylographiés locaux sont juste un petit chemin dans lequel vous pouvez désaccentuer comment et comment mettre ainsi l'accent sur quel. Si c'est la bonne chose à faire dans un cas particulier, est un jugement d'appel. Alors je dis aux gens que si le type est pertinent et son choix est crucial pour fonctionnement continu de la méthode, n'utilisez pas de typage implicite. La dactylographie explicite dit "je vous le dis comment cela fonctionne pour une raison, payer attention." La dactylographie implicite dit: n'est pas grave un peu de savoir si cette c'est un Liste ou d'un Client [], ce qui importe est qu'il est une collection de clients."

personnellement je n'ai pas tendance à l'utiliser si le type n'est pas raisonnablement évident - où J'inclus des requêtes LINQ comme étant "raisonnablement évident". Je ne le ferais pas pour Directory.GetFiles par exemple, car il n'est pas vraiment évident que cela renvoie un string[] au lieu de (disons) un FileInfo[] (ou quelque chose d'autre entièrement) - et cela fait une grande différence à ce que vous n'avez plus tard.

S'il y a un appel de constructeur sur le côté droit de l'opérateur d'affectation, Je suis beaucoup plus susceptible d'aller avec var : il est évident ce que le type sera. Cela est particulièrement pratique avec les types génériques complexes, par exemple Dictionary<string,List<int>> .

41
répondu Jon Skeet 2008-10-25 19:25:47

personnellement, je n'utilise var Qu'en deux endroits:

  1. Avec les types anonymes, c'est à dire. Lié à LINQ (où var est nécessaire dans certains cas)
  2. lorsque la déclaration déclare et construit un type spécifique au même type

ie. c'est un exemple du point 2:

var names = new List<String>();

édité : ceci en réponse à la question de Jon Skeet.

le la réponse ci-dessus a en fait été simplifiée. Fondamentalement, j'utilise var où le type est soit:

  1. inutile de savoir (pas que beaucoup d'endroits cependant)
  2. Impossible à savoir (LINQ, types anonymes)
  3. autrement connu, ou clair du code

Dans le cas d'une méthode de fabrique, où tout ce que vous devez savoir à l'endroit où vous écrivez le code, c'est que l'objet que vous get back est un descendant d'un certain type, et que un certain type a une méthode d'usine statique, alors j'utiliserais var . Comme ceci:

var connection = DatabaseConnection.CreateFromConnectionString("...");

L'exemple ci-dessus est un exemple concret de mon code. Il est clair, du moins pour moi et les personnes qui utilisent ce code, que connection est un descendant de DatabaseConnection, mais le type exact n'est pas nécessaire pour ni comprendre le code, ni de l'utiliser.

11
répondu Lasse Vågsæther Karlsen 2008-10-25 19:44:41

j'ai essayé le style" use var everywhere"... et voilà pourquoi je n'ai pas continué à l'utiliser.

  1. dégradation de la lisibilité à certains moments
  2. Limites Intellisense après =
  3. taper " var "n'était vraiment pas beaucoup plus court que de taper" int"," string", etc. surtout avec intellisense.

cela dit, Je l'utilise toujours avec LINQ.

9
répondu Inisheer 2008-10-25 19:41:45

venant du pays de la programmation fonctionnelle, où l'inférence de type règle la journée, j'utilise var pour tous les locaux où possible.

dans Visual Studio, si vous vous demandez un jour Quel est le type de local, tout ce que vous avez à faire est de le survoler avec votre souris.

3
répondu yfeldblum 2008-10-26 04:21:12

Ce post ont quelques bonnes lignes directrices sur l'utilisation de la var interface de type ou de types d'objet.

3
répondu Andres Denkberg 2008-10-25 20:15:41

j'ai tendance à utiliser var partout, mais mes collègues dit stop, c'est moins lisible pour nous. Donc maintenant j'utilise var seulement sur les types anonymes, les requêtes LINQ et où est le constructeur sur le côté droit.

3
répondu Aleš Roubíček 2008-12-13 16:41:04

je pense qu'il est intéressant de noter comment cela est habituellement manipulé à Haskell. Grâce à L'isomorphisme Curry-Howard , le type (le plus général) de n'importe quelle expression dans Haskell peut être inféré, et donc les déclarations de type ne sont essentiellement pas nécessaires n'importe où, avec quelques exceptions; par exemple, parfois vous voulez délibérément limiter le type à quelque chose de plus spécifique que serait inféré.

bien sûr, ce qui est nécessaire et ce qui est ce qui est recommandé n'est pas la même chose; dans la pratique, la convention semble être que les définitions de haut niveau ont toujours des déclarations de type, tandis que les définitions localisées ont les déclarations de type laissées de côté. Cela semble établir un bon équilibre entre la clarté explicite de la définition dans son ensemble et la brièveté de la lisibilité des définitions locales d ' "aidant" ou de "temporaire". Si je comprends bien, vous ne pouvez pas utiliser var pour des définitions "de haut niveau" (comme une méthode ou fonction globale) en premier lieu, donc je suppose que cela correspond à "l'utilisation var partout" en C# monde. Bien sûr, taper " int "est le même nombre de touches que" var ", mais la plupart des exemples seront plus longs que cela.

1
répondu mithrandi 2008-10-25 21:46:39