20 votes

Initialisation des champs d'instance par rapport aux variables locales

Je me suis toujours demandé pourquoi, dans l'exemple suivant, il est acceptable de no initialiser le champ d'instance (en tenant compte du fait qu'il aura sa valeur par défaut) et y accéder, tandis que les variables locales apparemment debe être initialisé, même si je l'initialise à la valeur par défaut, il sera de toute façon...

  public class TestClass
  {
    private bool a;

    public void Do()
    {
      bool b; // That would solve the problem: = false;
      Console.WriteLine(a);
      Console.WriteLine(b); //Use of unassigned local variable 'b'
    }
  }

30voto

Jon Skeet Points 692016

Pour les variables locales, le compilateur a une bonne idée du flux - il peut voir une "lecture" de la variable et une "écriture" de la variable, et prouver (dans la plupart des cas) que la première écriture aura lieu avant la première lecture.

Ce n'est pas le cas des variables d'instance. Considérez une simple propriété - comment savoir si quelqu'un va la définir avant de l'obtenir ? Il est donc impossible d'appliquer des règles raisonnables - il faut donc soit s'assurer que tous ont été définis dans le constructeur, ou leur permettre d'avoir des valeurs par défaut. L'équipe C# a choisi cette dernière stratégie.

6voto

Dzmitry Huba Points 3333

Il est régi par les règles d'assignation définies en C#. La variable doit être définitivement assignée avant d'être accessible.

5.3 Assignation définitive

A un endroit donné du code exécutable d'un membre de fonction, une variable est dite définitivement assignée si le compilateur peut prouver, par une analyse de flux statique particulière (§5.3.3), que la variable a été initialisée automatiquement ou a été la cible d'au moins une assignation.

5.3.1 Variables initialement assignées

Les catégories suivantes de variables sont classées comme initialement affectées :

  • Variables statiques.

  • Variables d'instance des instances de la classe.

  • Variables d'instance des variables struct initialement attribuées.

  • Éléments du tableau.

  • Paramètres de valeur.

  • Paramètres de référence.

  • Variables déclarées dans une clause catch ou une instruction foreach.

5.3.2 Variables initialement non attribuées

Les catégories suivantes de variables sont classées comme initialement non attribuées :

  • Variables d'instance de variables struct initialement non assignées.

  • Paramètres de sortie, y compris la variable this des constructeurs de structures d'instance.

  • Les variables locales, sauf celles déclarées dans une clause catch ou une instruction foreach.

2voto

Bevan Points 20976

Lorsqu'un morceau de mémoire est alloué à une nouvelle instance d'objet, le runtime inscrit des zéros dans tout le bloc, afin de s'assurer que le nouvel objet démarre dans un état connu. C'est pourquoi les nombres entiers ont la valeur 0 par défaut, les doubles la valeur 0.0 par défaut, les pointeurs et les références d'objets la valeur null, et ainsi de suite.

Il serait possible, en théorie, de faire de même pour les cadres de pile alloués dans le cadre d'appels de méthode. La surcharge, cependant, serait élevée - il faudrait radicalement ralentir les appels à d'autres méthodes, et n'est donc pas tentée.

1voto

Razzie Points 14705

Les variables d'instance ont une valeur par défaut. Extrait de la spécification C# 3.0 :

5.1.2.1 Variables d'instance dans les classes

Une variable d'instance d'une classe vient existe lorsqu'une nouvelle instance de cette classe est créée, et cesse d'exister d'exister lorsqu'il n'y a plus de références à cette instance et que le finalisateur de l'instance finaliseur de l'instance (s'il existe) a été exécuté.

La valeur initiale d'une instance d'une classe est la valeur par (§5.2) du type de la variable.

Aux fins de l'affectation définitive d'affectation définitive, une variable d'instance est considérée comme initialement assignée.

1voto

Steven Robbins Points 18791

C'est une limitation du compilateur. Le compilateur essaie d'empêcher l'utilisation d'une variable non assignée chaque fois qu'il le peut, ce qui est une bonne chose car l'utilisation de variables non initialisées était une source courante de bogues dans le vieux code C.

Le compilateur ne peut cependant pas savoir si la variable d'instance est initialisée avant l'appel de cette méthode, car elle peut être définie par n'importe quelle autre méthode, qui peut être appelée dans n'importe quel ordre par du code externe.

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