2009-12-15 7 views
11

Il semble que de plus en plus du code C# Je lis utilise l'identificateur de type var:Y at-il une raison technique d'utiliser ou de ne pas utiliser var en C# lorsque le type est connu?

foreach (var itemChange in ItemChanges) 
{ 
    //... 
} 

au lieu de explicitement indiquant le type:

foreach (ItemChange itemChange in ItemChanges) 
{ 
    //... 
} 

même lorsque le type est connu.

J'utilise toujours la version explicite dernière juste parce que je pense que quelqu'un la lisant plus tard comprendra plus rapidement quel type est une variable que si vous utilisez var.

Mais y a-t-il technique raison d'utiliser l'un ou l'autre?

+0

duplication possible de [Quel est le point du mot-clé var?] (Http://stackoverflow.com/questions/209199/whats-the-point-of-the-var-keyword) –

+0

également une dupe de: http : //stackoverflow.com/questions/41479/use-of-var-keyword-in-c –

Répondre

12

Non, juste lisibilité.

+2

J'aime cette réponse. Court et doux. – RCIX

21

Il n'y a pas de raison technique. Si le type ne peut pas être déduit lors de la compilation, le code ne sera pas compilé.

Vous avez raison de dire qu'il existe des cas où il peut être préférable d'utiliser un type explicite pour la lisibilité, par ex.

var obj = SomeMethod(); // what's the type? you'd have to inspect SomeMethod() 
SomeClass obj = SomeMethod(); // the type is obvious 

mais d'autres cas où l'utilisation de var est parfaitement logique, par ex.

var obj = new SomeClass(); // the type is obvious 
SomeClass obj = new SomeClass(); // the duplication of type is unnecessary 
+4

Mais (a) cela prouve juste que 'SomeMethod' est mal nommé, pas que l'information de type est utile, et (b) pourquoi vous souciez-vous du type concret de toute façon? Je vois beaucoup de réponses au débat 'var' qui suppose que l'information de type concret facilite la lisibilité sans citer aucune preuve qu'il en est ainsi. Les utilisateurs de langages dynamiques et fonctionnels auraient tendance à être fortement en désaccord avec l'affirmation selon laquelle les informations de type en ligne sont une bonne chose. –

+1

Je comprends d'où vous venez, cependant a) vous ne pouvez pas avoir le contrôle sur le nom de 'SomeMethod' b) Je ne me soucie pas particulièrement, c'est juste un problème de lisibilité, certaines personnes peuvent préférer être en mesure de connaître le type de la variable à mesure qu'elle lit le code suivant c) 'Utilisateurs de langages dynamiques et fonctionnels' - assez juste. Je fais aussi du codage IronPython et je peux comprendre ce contexte. Cependant, il s'agit d'une question C# –

2

N ° Utiliser var où il améliore la lisibilité et vice versa.

2

var est une fonctionnalité C# 3.x +, n'est-ce pas? sans utiliser cela, votre code est plus compatible avec d'autres versions aussi.

Et il y a beaucoup de questions intéressantes, quand vous la recherche « var C# »

+0

Il s'agit en fait d'une fonctionnalité C# 3, mais fonctionnera très bien si vous ciblez. Net 2.0 – philsquared

+0

Eh bien, var est implémenté dans .Net 2.0 comme un truc du compilateur, nous l'utilisons occasionnellement dans notre .Net2 .0 application. –

+0

Merci Phil Nash, Vous avez raison, corrigé. – YOU

3

En général, aucune raison technique. La lisibilité - dans les deux sens - est le seul facteur réel.

Cependant, une petite mise en garde est que var déduira le statique type de la variable. Si vous voulez un type sub ou super classe, vous devrez faire le casting vous-même. Dans le cas d'un foreach, comme dans votre exemple, vous pouvez généralement obtenir la rétrogradation effectuée pour vous "gratuitement" en déclarant simplement votre variable de boucle avec le type de sous-classe.

L'exemple classique est itérez un NodeList XML que vous connaissez est une liste de XmlElement, mais Nodelist est entré comme une collection de XmlNode s. Bien sûr, vous pouvez utiliser une distribution ou un as pour récupérer le type que vous voulez, mais cela semblerait aller à l'encontre de l'utilisation de l'inférence de type :-)

Bien sûr, le compilateur vous le dira dès que possible. Lorsque vous essayez d'utiliser un membre du nœud qui n'est disponible que pour XmlElement, il ne s'agit donc pas strictement d'une différence technique.


Une autre chose qui est un peu ennuyeux est que si vous utilisez un outil comme ReSharper, il est très agressif qui suggère que vous utilisez var dans toutes les situations possibles. Il est particulièrement ennuyeux quand il vous recommande de changer, par exemple, une déclaration int dans un var!

Cependant, sauf si vous désactivez cette fonction, vous obtiendrez moins de «bruit» de Resharper, plus vous utiliserez var.

3

La seule raison technique que je connaisse est que vous pouvez effectuer des lancements implicites sans var, par ex.

int i = 5; 
double a = i; // implicit cast with explicit types 

mais ici je préfère var comme il fait le casting explicite; alors que je ne me soucie pas tant sur les types que je fais attention lorsque j'effectuer une conversion de type de changement de représentation:

var a = (double)i; // explicit cast with implicit types 

Mais vraiment la raison générale est la lisibilité, comme vous le dites. La question que vous devez vous poser est pourquoi vous pensez que le type exact de béton est important pour la lisibilité? Ecrivez-vous toujours des requêtes Linq appelant le type concret, par ex.

from ItemChange itemChange in ItemChanges 

// instead of 

from itemChange in ItemChanges 

De même, appelez-vous toujours les arguments de type à des méthodes génériques au lieu d'utiliser l'inférence de type, par ex.

ItemChanges.Select<ItemChange, ItemChange>((ItemChange itemChange) => ...); 

// instead of 

ItemChanges.Select(itemChange => ...); 

Ou êtes-vous heureux de laisser le compilateur faire un travail pour vous et laissez-le travailler les types, à la « charge » de ne pas avoir les informations de type explicitement? Si vous êtes satisfait de l'inférence de type dans linq et des méthodes génériques, alors vous avez déjà pris la décision que vous n'avez pas de types explicitement définis partout, et vous n'avez probablement pas trouvé votre code être moins lisible en conséquence (en fait, vous avez probablement trouvé tout le contraire). Donc, en utilisant var est juste une autre étape dans le même chemin que vous êtes déjà sur.

+0

La diffusion explicite peut être importante dans certaines situations, par exemple si l'énumérateur d'une collection renvoie "objet" au lieu du type exact. Je pense que SPListItemCollection est un tel exemple, mais je pense que cela s'applique à toutes les collections non génériques. –

+0

@Michael - d'accord. J'aurais dû être plus clair sur la différence entre les changements de représentation et ceux qui préservent la représentation (ceux que je préfère expliciter explicitement avec un opérateur de casting sont ceux qui changent de représentation). Oui, je pense que l'utilisation du nom de type est plus claire que celle d'une distribution pour les coercitions de type préservant la représentation. –

3

var est une fonction obligatoire que dans le type anonyme

C# 3.0 parce que le code suivant

var v = new { Amount = 108, Message = "Hello" }; 

créer dynamiquement un nouveau type anonyme, l'utilisation var est obligatoire. Par exemple, var est particulièrement utile dans Linq où les types sont souvent créés dynamiquement.

Dans toutes les autres situations, c'est seulement une question de goût pour l'application finale (c'est résolu pendant la compilation). Mais pour les lecteurs de code, je pense que 'var' est moins informatif que le type lui-même.

+1

Parfois je pense qu'il devrait y avoir quelque chose comme un mot-clé 'anon' pour ceux au lieu de' var'. –

0

Il n'y a aucune raison technique d'utiliser var, autre que des types anonymes, dans un état donné du programme. Cependant, l'utilisation de var permet au programme de changer sans que vous ayez besoin de le modifier.Compte tenu

public int SomeMethod(){} 
public List<T> SomeOtherMethod<T>(T parameter); 

puis

var x = SomeMethod(); 
var y = SomeOtherMethod(x); 

Est-ce que le travail (et y sera List<int>). Si vous aviez utilisé

int x = SomeMethod(); 
List<int> y = SomeOtherMethod(x); 

alors si SomeMethod() ont été changés pour revenir long, alors vous devez changer la définition de y.

J'ai vu ce genre de chose se propager dans un programme, nécessitant des centaines de changements. Le cas particulier était en train de changer le code d'accès aux données pour renvoyer ReadOnlyCollection<T> plutôt que List<T>. Il y avait tellement de changements de code requis, que j'ai changé toutes les mentions explicites de List<T> en var, et le code n'aura jamais besoin de changer à nouveau.

-1

Oui, ils sont différents. var supprime le type de données d'origine et une vérification de type de données, donc c'est plus dangereux.

Type-chèques

Une définition variable normale comprend un type de données-contrôle sur l'affectation initiale.

T a = init;  // type-checked 
a = b;   // type-checked 
a = c;   // type-checked 

Ce manque lorsque vous utilisez var

var a = init; // NOT type-checked 
a = b;   // type-checked 
a = c;   // type-checked 

Ces tests de compilation sont la colle qui maintient ensemble les grands programmes. Les enlever est stupide.

accidentelle changements

Une définition variable normale a un type fixe - il ne peut pas être modifié accidentellement. Lorsque vous supprimez le type de données initial, vous permettez que le type de la variable soit modifié accidentellement. Toute modification apportée à l'expression initiale peut modifier le type de données de la variable.

var a = init(e);   // datatype changes with init and e 

Avec le temps, à mesure que le logiciel est édité, le type de données peut être accidentellement modifié.
Il pourrait déjà être arrivé, et vous ne pouvez pas le dire.

Exemple:

public double MaxValue = 1.2; 

    ... meanwhile, in another source file ... 

    var x = MaxValue - 1; 
    var y = IsFull(x); 

x et les types de données de y peuvent être accidentellement changer en éditant MaxValue.
Q. Est-ce déjà arrivé?

Résumé

L'utilisation var tourne le type de données de la variable locale dans une partie mobile sans contrôle.
Plus les pièces mobiles d'une machine sont nombreuses, plus elle risque de se briser.

Les types de données explicites empêchent les bogues.

Questions connexes