53 votes

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

C'est une question que je me pose toujours lorsque je programme : Que faut-il utiliser quand on écrit du code :

var myFiles = Directory.GetFiles(fullPath);

ou

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

var est nouveau et est un Variables locales implicitement typées Nous ne pouvons donc l'utiliser que localement et elle est soumise à des règles telles que l'impossibilité d'être nulle, etc., mais je me demande si l'utilisation "normale" présente un quelconque avantage.

La partie "normalement" dit, pas dans Types d'anonymes , Initialisateurs d'objets et de collections y Expressions de requêtes où c'était l'intention d'utiliser l'objet anonyme var, donc ce que je veux dire c'est... comme dans l'exemple ci-dessus.

qu'en pensez-vous ?

61voto

Robert Rossney Points 43767

Au-delà de l'utilisation évidente de var avec LINQ, je l'utilise aussi pour abréger les déclarations de variables poilues pour plus de lisibilité, par ex :

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

En général, la frappe statique me procure une sorte de confort (faute d'un meilleur terme) qui me fait hésiter à l'abandonner. J'aime avoir l'impression que je sais ce que je fais lorsque je déclare une variable. Déclarer une variable, ce n'est pas seulement dire quelque chose au compilateur, c'est dire quelque chose à la personne qui lit votre code.

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

List<string> list = MyMethod();

Évidemment, non ? En fait, voici un endroit que vous pourriez tout aussi bien utiliser var .

C'est vrai. Mais ce du code ne se contente pas de déclarer une variable, elle me dit ce que la personne qui l'a écrite a l'intention de faire :

IEnumerable<string> list = MyMethod();

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

Bien sûr, vous ne l'abandonnez pas si vous ne l'utilisiez pas au départ. Si vous êtes le genre de développeur qui écrirait cette ligne de code, vous savez déjà que vous n'utiliseriez pas la fonction var là.

Editar:

Je viens de relire le post de Jon Skeet, et cette citation d'Eric Lippert m'a sauté aux yeux :

Les locals implicitement typés ne sont qu'un petit moyen de minimiser le comment et de mettre l'accent sur le quoi.

Je pense qu'en fait, dans de nombreux cas, utiliser le typage implicite revient à laisser le quoi implicite. C'est juste bien de ne pas s'attarder sur le quoi. Par exemple, je vais écrire une requête LINQ comme :

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

Quand je lis ce code, une des choses que je pense en le lisant est " rows est un IEnumerable<DataRow> ." Parce que je sais que ce que les requêtes LINQ retournent est IEnumerable<T> et je peux voir le type d'objet sélectionné juste là.

C'est un cas où le quoi n'a pas a été rendu explicite. Il m'a été laissé le soin de déduire.

Maintenant, dans environ 90% des cas où j'utilise LINQ, cela n'a pas la moindre importance. Parce que 90% du temps, la prochaine ligne de 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> - où de nombreux types d'objets différents sont interrogés, il n'est pas possible de placer la déclaration de la requête à côté de l'itération, et il serait utile de pouvoir inspecter rows avec IntelliSense. Et c'est une question de quoi, pas de comment.

42voto

Jon Skeet Points 692016

Vous obtiendrez une grande variété d'opinions à ce sujet, de "utilisez var partout" à "n'utilisez var qu'avec les types anonymes, lorsque vous y êtes fondamentalement obligé". J'aime bien Le point de vue d'Eric Lippert :

Tout code est une abstraction. Ce que ce que le code fait "réellement" est manipuler des données ? Non. Des nombres ? Des bits ? Non. Des tensions ? Non. Des électrons ? Oui, mais comprendre le code au niveau des électrons est une mauvaise idée ! L'art du codage consiste à déterminer quel est le bon niveau d'abstraction pour le public.

Dans un langage de haut niveau, il y a toujours cette tension entre ce que le le code fait (sémantiquement) et COMMENT le le code l'accomplit. Maintenance les programmeurs de maintenance doivent comprendre à la fois le quoi et le comment s'ils doivent réussir à effectuer des changements.

L'intérêt de LINQ est qu'il dé-emphase massivement le "comment" et et met massivement l'accent sur le "quoi". En utilisant une compréhension de requête, le programmeur dit au futur futur public "Je crois que vous devriez ni savoir ni vous soucier de la façon dont cet ensemble ensemble de résultats est calculé, mais vous devriez vous préoccuper de ce que la sémantique de l'ensemble résultant". Ils rendent le code plus proche des processus métier mis en œuvre et et plus loin des bits et des électrons qui le font fonctionner.

Les locales implicitement typées sont juste une une petite façon de dédramatiser le comment et ainsi mettre l'accent sur le quoi. Si c'est la bonne chose à faire à faire dans un cas particulier est une est une question de jugement. Je dis donc aux gens que si la connaissance du type est pertinente et que son choix est crucial pour fonctionnement continu de la méthode, alors n'utilisez pas le typage implicite. Le typage explicite dit "Je vous dis comment cela fonctionne pour une raison, faites attention". Le typage implicite dit "il n'a pas d'importance si ce chose est une liste ou un Customer[], ce qui compte c'est que ce soit une collection de clients".

Personnellement, je ne tendent de l'utiliser si le type n'est pas raisonnablement évident - j'inclus les requêtes LINQ dans la catégorie "raisonnablement évidentes". Je ne le ferais pas pour Directory.GetFiles par exemple, car il n'est pas vraiment évident que cela renvoie une string[] au lieu de (disons) un FileInfo[] (ou quelque chose d'autre) - et cela fait une grande différence pour ce que vous ferez plus tard.

S'il y a un appel au constructeur à droite de l'opérateur d'affectation, je suis beaucoup plus enclin à opter pour var : il est évident de savoir quel sera le type. C'est particulièrement pratique avec les types génériques complexes, par ex. Dictionary<string,List<int>> .

11voto

Lasse V. Karlsen Points 148037

Personnellement, je n'utilise var qu'à deux endroits :

  1. Avec des types anonymes, c'est-à-dire liés à 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

c'est-à-dire que c'est un exemple du point 2 :

var names = new List<String>();

Publié sur : Ceci en réponse à la question de Jon Skeet.

La réponse ci-dessus était en fait simplifiée. En gros, j'utilise var où le type est soit :

  1. Inutile de le savoir (pas dans beaucoup d'endroits cependant)
  2. Impossible de savoir (LINQ, types anonymes)
  3. Autrement connu, ou clair dans le code

Dans le cas d'une méthode de fabrique, où tout ce que vous avez besoin de savoir à l'endroit où vous écrivez le code est que l'objet que vous récupérez est un descendant d'un certain type, et que un certain type a une méthode d'usine statique, alors j'utiliserais var . Comme ça :

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

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

9voto

Inisheer Points 11582

J'ai essayé le style "utiliser var partout"... et voici pourquoi je n'ai pas continué à l'utiliser.

  1. Une lisibilité dégradée par moments
  2. Limite Intellisense après =
  3. Taper "var" n'était pas vraiment plus court que de taper "int", "string", etc., surtout avec intellisense.

Cela dit, je l'utilise toujours avec LINQ.

3voto

Andres Denkberg Points 326

Ce site poste ont de bons conseils pour savoir quand utiliser les types d'interface var ou les types d'objet.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X