37 votes

Utilisation du type "var" dans la déclaration variable

Notre audit interne nous suggère d'utiliser une déclaration variable explicite au lieu d'utiliser le mot clé . Ils font valoir que l'utilisation de "peut conduire à des résultats inattendus dans certains cas".

Je ne suis pas au courant d'une différence entre la déclaration de type explicite et l'utilisation `` d'une fois que le code est compilé à MSIL.

Le vérificateur est un professionnel respecté, donc je ne peux pas simplement refuser une telle suggestion.

50voto

LukeH Points 110965

Comment à ce sujet...

double GetTheNumber()
{
    // get the important number from somewhere
}

Et puis d'ailleurs...

var theNumber = GetTheNumber();
DoSomethingImportant(theNumber / 5);

Et puis, à un certain moment dans l'avenir, quelqu'un remarque qu' GetTheNumber seulement jamais renvoie des nombres entiers, de sorte refactors le retour d' int plutôt que d' double.

Bang! Pas d'erreurs de compilation et vous commencez à voir des résultats inattendus, parce que ce qui était précédemment l'arithmétique à virgule flottante est maintenant devenu l'arithmétique des nombres entiers, sans que personne ne le remarque.

Ceci dit, ce genre de chose devrait être pris par des tests unitaires, etc, mais il est encore un potentiel de gotcha.

23voto

ChrisF Points 74295

J'ai tendance à suivre ce schéma:

Si le type de retour change jamais, ce code compilera toujours. Dans le meilleur des cas, vous obtenez des erreurs de compilation plus loin, mais dans le pire des cas (selon la façon dont il est utilisé), vous ne pouvez pas. Ce que vous obtiendrez probablement dans ce cas est des erreurs de run-time qui pourraient être très difficiles à traquer.

14voto

Daren Thomas Points 26812

Certains cas pourraient vraiment conduire à des résultats inattendus. Je suis un `` fan moi-même, mais cela pourrait mal tourner:

Évidemment, il s'agit d'une erreur et non d'un "résultat inattendu". Mais c'est un gotcha...

13voto

badbod99 Points 3588

var n'est pas un type dynamique, c'est simplement du sucre syntaxique. La seule exception à cette règle avec les types Anonymes. À partir de la Microsoft Docs

Dans de nombreux cas, l'utilisation de la var est facultatif et est à seulement syntaxique de commodité. Toutefois, lorsqu'une variable est initialisée avec un type anonyme, vous devez déclarer la variable var si vous avez besoin d'accéder aux propriétés de l'objet à un moment plus tard.

Il n'y a pas de différence une fois compilé à l'IL , sauf si vous avez explicitement défini le type différent de celui qui serait implicite (bien que je ne peux pas penser à pourquoi vous voulez). Le compilateur ne vous permettra pas de changer le type d'une variable déclarée avec le var à tout moment.

À partir de la documentation de Microsoft (encore une fois)

Une tapée implicitement variable locale est fortement typé comme si vous aviez déclaré le type de vous-même, mais le compilateur détermine le type de

Dans certains cas, var peut impeed des raisons de lisibilité. Plus Microsoft docs de l'état:

L'utilisation de la var n'ont au moins la possibilité de rendre votre code plus difficile à comprendre pour les autres développeurs. Pour cette raison, le C# documentation utilise généralement var uniquement lorsque cela est requis.

8voto

0xA3 Points 73439

Dans le non-génériques monde, vous pourriez obtenir un comportement différent lors de l'utilisation d' var au lieu de le taper à chaque fois qu'une conversion implicite aurait lieu, par exemple au sein d'un foreach boucle.

Dans l'exemple ci-dessous, une conversion implicite de object de XmlNode a lieu (la non-générique IEnumerator seulement l'interface de retours object). Si vous remplacez simplement la déclaration explicite de la variable de boucle avec l' var mot-clé, cette conversion implicite ne prend plus de place:

using System;
using System.Xml;

class Program
{
    static void Foo(object o)
    {
        Console.WriteLine("object overload");
    }

    static void Foo(XmlNode node)
    {
        Console.WriteLine("XmlNode overload");
    }

    static void Main(string[] args)
    {
        XmlDocument doc = new XmlDocument();
        doc.LoadXml("<root><child/></root>");

        foreach (XmlNode node in doc.DocumentElement.ChildNodes)
        {
            Foo(node);
        }

        foreach (var node in doc.DocumentElement.ChildNodes)
        {
            // oops! node is now of type object!
            Foo(node);
        }
    }
}

Le résultat est que le code produit en fait des sorties différentes selon que vous avez utilisé var ou un type explicite. Avec var le Foo(object) de surcharge sera exécutée, sinon l' Foo(XmlNode) de surcharge sera. La sortie du programme ci-dessus est donc:

XmlNode surcharge
objet de surcharge

Notez que ce comportement est parfaitement en fonction de la spécification du langage C#. Le seul problème est qu' var déduit d'un autre type (object) que vous attendez et que cette inférence n'est pas évident de regarder le code.

Je n'ai pas ajouter le IL le garder court. Mais si vous voulez, vous pouvez jeter un oeil à ildasm de voir que le compilateur génère différentes instructions IL pour les deux boucles foreach.

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