Question

    

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

    
            
  •              Utilisation du mot clé var en C #                                      86 réponses                          
  •     
    

C’est une question que je me pose toujours lors de la programmation: Que faut-il utiliser lors de l’écriture du code:

var myFiles = Directory.GetFiles(fullPath);

ou

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

var est nouveau et constitue une variable locale implicitement typée . Par conséquent, nous ne pouvons utiliser que localement et ses règles sont telles que ne peuvent pas l'être. null, etc., mais je me demande si nous aurions le moindre avantage à l'utiliser & "normalement &";

Le " normalement " une partie indique, pas dans les types anonymes , les initialiseurs d’objet et de collection et les expressions de requête , dans lesquels l’intention était d’utiliser l’objet anonyme anonymes, Je veux dire est ... juste comme l'exemple ci-dessus.

quelles sont vos pensées?

Était-ce utile?

La solution

Au-delà de l'utilisation évidente de var avec LINQ, je l'utilise également pour abréger les déclarations de variables poilues aux fins de lisibilité, par exemple:

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

En général, le typage statique me procure une sorte de réconfort (faute d’un meilleur mot) qui me rend réticent à l’abandonner. J'aime sentir que je sais ce que je fais quand je déclare une variable. Déclarer une variable ne dit pas simplement quelque chose au compilateur, c'est aussi dire à la personne qui lit votre code.

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 ce serait ainsi que 90% des développeurs C # l'écriraient probablement:

List<string> list = MyMethod();

Évidemment, non? En fait, voici un endroit où vous pourriez tout aussi bien utiliser rows.

Assez vrai. Mais cette version du code ne se limite pas à déclarer une variable, elle me dit 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 modifier cette liste, ni utiliser un index pour accéder à ses membres. Tout ce que je vais faire, c'est l'itérer à travers elle. & C'est beaucoup d'informations à faire passer dans une seule ligne de code. C’est quelque chose que vous abandonnez si vous utilisez IEnumerable<DataRow>.

Bien sûr, vous ne l'abandonnez pas si vous ne l'utilisiez pas en premier lieu. Si vous êtes le genre de développeur qui écrirait cette ligne de code, vous savez déjà que vous ne l'utiliseriez pas IEnumerable<T> ici.

Modifier:

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

  

Les sections locales implicitement typées ne sont qu’un moyen, parmi d’autres, de minimiser l’importance du comment et de souligner ainsi le quoi.

Je pense que dans de nombreux cas, le typage implicite laisse le quoi implicite. C'est juste OK de ne pas s'attarder sur le quoi. Par exemple, j'écrirai avec désinvolture une requête LINQ telle que:

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

Lorsque je lis ce code, l'une des choses que je pense quand je le lis est & "; <=> est un <=>. &"; Parce que je sais que ce que les requêtes LINQ renvoient est <=>, et je peux voir le type d'objet sélectionné ici même.

C’est un cas où ce que n’a pas été explicite. Il me reste à en déduire.

Maintenant, dans environ 90% des cas où j'utilise LINQ, cela n'a pas d'importance. Comme 90% du temps, la ligne de code suivante est la suivante:

foreach (DataRow r in rows)

Mais il n’est pas difficile d’envisager du code dans lequel il serait très utile de déclarer <=> comme <=> - code dans lequel de nombreux types d’objets étaient interrogés, il n’était pas faisable de placer la déclaration de requête. à côté de l'itération, et il serait utile de pouvoir inspecter <=> avec IntelliSense. Et c'est une chose quoi, pas une chose comment.

Autres conseils

Vous obtiendrez une grande variété d’opinions sur ce sujet - de & "utiliser var partout &"; pour & "utiliser uniquement la var avec les types anonymes, où vous devez fondamentalement. &"; J'aime la position d'Eric Lippert :

  

Tout code est une abstraction. C'est quoi   le code est & # 8220; vraiment & # 8221; faire est   manipuler des données? N ° de chiffres? Morceaux?   Nb de tensions? Nbre d'électrons? Oui mais   comprendre le code au niveau de   les électrons est une mauvaise idée! L'art de   le codage consiste à déterminer ce que le droit   niveau d'abstraction est pour le   public.

     

Dans une langue de haut niveau, il y a   toujours cette tension entre ce que le   fait le code (sémantiquement) et COMMENT le   le code l'accomplit. Entretien   les programmeurs doivent comprendre à la fois   le quoi et le comment s'ils & # 8217; vont   pour réussir à apporter des changements.

     

L’intérêt principal de LINQ est qu’il   massivement insiste sur le " comment " et   souligne massivement le & "Qu'est-ce que &"; Par   en utilisant une compréhension de la requête, le   programmeur dit à l'avenir   public &: je crois que vous devriez   ni savoir ni se soucier exactement comment cela   jeu de résultats est en cours de calcul, mais vous   devrait se soucier beaucoup de ce que le   la sémantique de l'ensemble résultant est. "   Ils rendent le code plus proche de la   processus commercial mis en œuvre et   plus loin des bits et des électrons   qui le fait aller.

     

Les sections locales implicitement typées ne sont qu'un   petit moyen dans lequel vous pouvez insister   le comment et ainsi souligner la   quoi. Que ce soit la bonne chose   faire dans un cas particulier est un   appel du jugement. Alors je dis aux gens que   si la connaissance du type est pertinente   et son choix est crucial pour la   fonctionnement continu de la méthode,   alors n'utilisez pas de typage implicite.   La frappe explicite dit & "Je vous dis   comment cela fonctionne pour une raison, payer   attention &. Le typage implicite dit & "; Il   ça ne compte pas! & # 8217; importe peu si cette   chose est une liste ou une   Client [], ce qui compte, c’est   une collection de clients. & ";

Personnellement, je n'ai pas tendance à l'utiliser si le type n'est pas raisonnablement évident - lorsque j'inclue les requêtes LINQ comme & "raisonnablement évident &"; Je ne le ferais pas pour Directory.GetFiles par exemple, car il n'est pas vraiment évident que cela retourne un string[] au lieu de (disons) un FileInfo[] (ou autre chose) - et cela fait une grande différence faire plus tard.

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

Personnellement, je n'utilise var que dans deux endroits:

  1. Avec les types anonymes, c'est-à-dire. LINQ-related (où var est requis dans certains cas)
  2. Lorsque l'instruction déclare et construit un type spécifique du même type

ie. Voici un exemple du point 2:

var names = new List<String>();

Modifié : cela répond à la question de Jon Skeet.

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

  1. Inutile de savoir (pas beaucoup d'endroits cependant)
  2. Impossible à connaître (LINQ, types anonymes)
  3. Autrement connu, ou effacer du code

Dans le cas d'une méthode 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 type a une méthode d'usine statique, j'utiliserais alors var . Comme ceci:

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 pour 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 l'utiliser.

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

  1. Une lisibilité parfois dégradée
  2. Limite Intellisense after =
  3. Taper " var " vraiment plus rapide que de taper & "; int &"; & "; chaîne &" ;, etc., en particulier avec intellisense.

Cela dit, je l’utilise toujours avec LINQ.

Venant du pays de la programmation fonctionnelle, où l’inférence de type gouverne le jour, j’utilise var pour toutes les sections locales dans la mesure du possible.

Dans Visual Studio, si vous vous demandez quel est le type d'un local, il vous suffit de le survoler avec votre souris.

This post fournit de bonnes indications sur le moment optimal pour utiliser une interface de type var ou des types d'objet.

J'ai tendance à utiliser var partout, mais mes collègues m'ont dit d'arrêter, c'est moins lisible. Donc, j’utilise maintenant <=> uniquement sur les types anonymes, les requêtes LINQ et où est le constructeur à droite.

Je pense qu’il est intéressant de noter comment cela se fait habituellement à Haskell. Merci à l’ l'isomorphisme de Curry-Howard , le type (le plus général) de toute expression dans Haskell peut être déduit et, par conséquent, les déclarations de type ne sont essentiellement requises nulle part, à quelques exceptions près; par exemple, vous voulez parfois délibérément limiter le type à quelque chose de plus spécifique que ce qui pourrait être déduit.

Bien sûr, ce qui est requis et ce qui est recommandé ne sont pas la même chose; en pratique, la convention semble être que les définitions de niveau supérieur 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 trouver un bon équilibre entre explicité pour la lisibilité de la définition dans son ensemble, en contraste avec la brièveté pour la lisibilité du & "Helper &" Local; ou " temporaire " définitions. Si je comprends bien, vous ne pouvez pas utiliser var pour & "Niveau supérieur &"; définitions (comme une méthode ou une fonction globale) en premier lieu, donc je suppose que cela se traduit par & "utiliser int partout où vous le pouvez &"; dans le monde C #. Bien sûr, en tapant & Quot; <=> & Quot; correspond au même nombre de frappes que & "; <=> &" ;, mais la plupart des exemples seront plus longs que cela.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top