Plus tôt, j'ai posé une question sur la raisonvar
pour laquelle je vois autant d'exemples utiliser le mot - clé et j'ai obtenu la réponse selon laquelle s'il n'est nécessaire que pour les types anonymes, il est néanmoins utilisé pour rendre l'écriture du code plus rapide / plus facile et simplement parce que.
En suivant ce lien ("C # 3.0 - Var is not objec"), j'ai vu que cela était var
compilé jusqu'au type correct dans l'IL (vous le verrez à mi-chemin de l'article).
Ma question est de savoir combien, le cas échéant, le code IL utilise le var
mot - clé, et serait-il même proche d'avoir un niveau mesurable sur les performances du code s'il était utilisé partout?
c#
performance
variables
var
Jeff Keslinke
la source
la source
var
très certainement avec "Rechercher toutes les références" dans Visual Studio 2019, donc si jamais il était cassé, il a été corrigé. Mais je peux confirmer que cela fonctionne aussi loin que Visual Studio 2012, donc je ne sais pas pourquoi vous avez affirmé que cela ne fonctionnait pas.var
ne sera pas considéré comme une référenceX
lorsque vous utilisez "Rechercher toutes les références" surX
. Fait intéressant, si vous utilisez « Trouver toutes les références » survar
dans cette déclaration, il va vous montrer des références àX
(bien qu'il ne sera toujours pas la liste de lavar
déclaration). De plus, lorsque le curseur est activévar
, il mettra en surbrillance toutes les instances deX
dans le même document (et vice versa).Réponses:
Il n'y a pas de code IL supplémentaire pour le
var
mot clé: l'IL résultant doit être identique pour les types non anonymes. Si le compilateur ne peut pas créer cet IL car il ne peut pas déterminer le type que vous aviez l'intention d'utiliser, vous obtiendrez une erreur de compilateur.La seule astuce consiste à
var
déduire un type exact où vous pourriez avoir choisi une interface ou un type parent si vous deviez définir le type manuellement.Mise à jour 8 ans plus tard
Je dois le mettre à jour car ma compréhension a changé. Je crois maintenant qu'il peut être possible
var
d'affecter les performances dans le cas où une méthode renvoie une interface, mais vous auriez utilisé un type exact. Par exemple, si vous avez cette méthode:Considérez ces trois lignes de code pour appeler la méthode:
Les trois compilent et s'exécutent comme prévu. Cependant, les deux premières lignes ne sont pas exactement les mêmes et la troisième ligne correspondra à la seconde plutôt qu'à la première. Parce que la signature de
Foo()
est de retourner unIList<int>
, c'est ainsi que le compilateur va construire labar3
variable.Du point de vue des performances, vous ne le remarquerez généralement pas. Cependant, il existe des situations où les performances de la troisième ligne peuvent ne pas être aussi rapides que celles de la première . Lorsque vous continuez à utiliser la
bar3
variable, le compilateur peut ne pas être en mesure de répartir les appels de méthode de la même manière.Notez qu'il est possible (probablement même) que la gigue puisse effacer cette différence, mais ce n'est pas garanti. En règle générale, vous devez toujours considérer
var
comme un non-facteur en termes de performances. Ce n'est certainement pas du tout comme utiliser unedynamic
variable. Mais dire que cela ne fait aucune différence peut être exagéré.la source
var i = 42;
(le type infers est int) n'est pas identique àlong i = 42;
. Ainsi, dans certains cas, vous pouvez émettre des hypothèses incorrectes sur l'inférence de type. Cela pourrait entraîner des erreurs d'exécution de cas insaisissables / de bord si la valeur ne correspond pas. Pour cette raison, il peut être judicieux d'être explicite lorsque la valeur n'a pas de type explicite. Ainsi, par exemple,var x = new List<List<Dictionary<int, string>()>()>()
serait acceptable, maisvar x = 42
est quelque peu ambigu et devrait être écrit ainsiint x = 42
. Mais à chacun ses goûts ...var x = 42;
n'est pas ambigu. Les littéraux entiers sont du typeint
. Si vous voulez un long littéral, vous écrivezvar x = 42L;
.Foo
renvoyé unList
, plutôt qu'un anIList
, alors les trois lignes se compileraient mais la troisième ligne se comporterait comme la première ligne , pas la seconde.Comme le dit Joel, le compilateur détermine au moment de la compilation quel type var devrait être, en fait, c'est juste une astuce que le compilateur effectue pour enregistrer les frappes, donc par exemple
est remplacé par
par le compilateur avant la génération de tout IL. L'IL généré sera exactement le même que si vous aviez tapé une chaîne.
la source
Comme personne n'a encore mentionné de réflecteur ...
Si vous compilez le code C # suivant:
Utilisez ensuite un réflecteur dessus, vous obtenez:
Donc, la réponse est clairement sans performances d'exécution!
la source
Pour la méthode suivante:
La sortie IL est la suivante:
la source
Le compilateur C # déduit le vrai type de la
var
variable au moment de la compilation. Il n'y a aucune différence dans l'IL généré.la source
Donc, pour être clair, c'est un style de codage paresseux. Je préfère les types natifs, étant donné le choix; Je prendrai ce petit peu de «bruit» pour m'assurer d'écrire et de lire exactement ce que je pense être au moment du code / débogage. * haussement d'épaules *
la source
var
affecte les performances du tout; vous exprimez simplement votre opinion quant à savoir si les gens devraient l'utiliser.int
car elle ne peut pas convertir automatiquement lefloat
, mais c'est exactement la même chose qui se produirait si vous l'utilisiez explicitementint
et que vous la modifiiez ensuitefloat
. Dans tous les cas, votre réponse ne répond toujours pas à la question "Est-ce que l'utilisationvar
affecte les performances?" (en particulier en termes d'IL généré)Je ne pense pas que vous ayez bien compris ce que vous avez lu. S'il est compilé dans le bon type, il n'y a pas de différence. Quand je fais ça:
Le compilateur sait que c'est un int et génère du code comme si j'avais écrit
Comme le dit le message auquel vous avez lié, il est compilé sur le même type. Ce n'est pas une vérification d'exécution ou toute autre chose nécessitant du code supplémentaire. Le compilateur détermine simplement quel type doit être, et l'utilise.
la source
Il n'y a aucun coût de performance d'exécution à utiliser var. Cependant, je soupçonne qu'il y a un coût de performance de compilation car le compilateur doit déduire le type, bien que cela soit très probablement négligeable.
la source
Si le compilateur peut faire l'inférence de type automatique, il n'y aura aucun problème de performances. Les deux généreront le même code
cependant, si vous construisez le type dynamiquement (LINQ ...),
var
c'est votre seule question et il y a un autre mécanisme à comparer pour dire quelle est la pénalité.la source
J'utilise toujours le mot var dans les articles Web ou les écrits de guides.
La largeur de l'éditeur de texte de l'article en ligne est petite.
Si j'écris ceci:
Vous verrez que le texte pré-code rendu ci-dessus est trop long et sort de la boîte, il est masqué. Le lecteur doit faire défiler vers la droite pour voir la syntaxe complète.
C'est pourquoi j'utilise toujours le mot-clé var dans les articles Web.
Le pré-code rendu entier tient juste dans l'écran.
En pratique, pour déclarer un objet, j'utilise rarement var, je compte sur intellisense pour déclarer un objet plus rapidement.
Exemple:
Mais, pour retourner un objet à partir d'une méthode, j'utilise var pour écrire du code plus rapidement.
Exemple:
la source
"var" est l'une de ces choses que les gens aiment ou détestent (comme les régions). Cependant, contrairement aux régions, var est absolument nécessaire lors de la création de classes anonymes.
Pour moi, var est logique lorsque vous actualisez directement un objet comme:
Cela étant dit, vous pouvez facilement faire simplement:
Dictionary<string, string> dict =
new et intellisense rempliront le reste pour vous ici.Si vous ne souhaitez travailler qu'avec une interface spécifique, vous ne pouvez pas utiliser var sauf si la méthode que vous appelez renvoie directement l'interface.
Resharper semble être du côté de l'utilisation de "var" partout, ce qui peut pousser plus de gens à le faire de cette façon. Mais je conviens en quelque sorte qu'il est plus difficile à lire si vous appelez une méthode et ce n'est pas évident ce qui est retourné par le nom.
var lui-même ne ralentit pas les choses, mais il y a une mise en garde à laquelle peu de gens pensent. Si vous le faites,
var result = SomeMethod();
le code après cela attend une sorte de résultat où vous appelleriez diverses méthodes ou propriétés ou autre chose. SiSomeMethod()
changé sa définition en un autre type mais qu'il respectait toujours le contrat que l'autre code attendait, vous venez de créer un bug vraiment désagréable (si pas de tests unitaires / d'intégration, bien sûr).la source
Cela dépend de la situation, si vous essayez d'utiliser ce code ci-dessous.
L'expression est convertie en "OBJET" et diminue tellement les performances, mais c'est un problème isolé.
CODE:
Résultats ci-dessus avec ILSPY.
Si vous souhaitez exécuter ce code, utilisez le code ci-dessous et obtenez la différence de temps.
Cordialement
la source