2012-02-10 3 views
47

Mon code est le suivantPourquoi compiler l'erreur "Utilisation de variable locale non affectée"?

int tmpCnt; 
if (name == "Dude") 
    tmpCnt++; 

Pourquoi est-il une erreur Use of unassigned local variable tmpCnt? Je sais que je ne l'ai pas explicitement initialisé mais en raison de Default Value Table un type de valeur est initialisé avec 0 de toute façon. La référence me rappelle également:

Rappelez-vous que l'utilisation de variables non initialisées en C# n'est pas autorisée.

Mais pourquoi dois-je le faire explicitement si c'est déjà fait par défaut? Ne gagnerait-il pas de performance si je n'avais pas à le faire? Je me demandais ...

+0

Quelqu'un peut-il m'aider avec le titre? Impossible de trouver un raccord pour celui-ci: -S – theknut

+0

J'ai une structure locale, jamais initialisée, compilée sans erreur. Aujourd'hui, j'ai créé une structure différente, traitée de manière identique, avec "erreur variable locale non initialisée". Tous ses * membres * ont été mis à une valeur avant utilisation, mais je ne pouvais pas d'abord le mettre à null, car il était «juste» une structure. La structure compilée ne contenait que des ints, des bools et des chaînes. Celui qui a donné l'erreur contenait aussi DateTimes. "MyStructType myStruct = new MyStructType();" tué l'erreur. Pas la première fois que j'ai été mordu en manquant quelque chose à quelques niveaux. – mickeyf

Répondre

90

Les variables locales ne sont pas initialisées. Vous devez les initialiser manuellement.

membres sont initialisés, par exemple:

public class X 
{ 
    private int _tmpCnt; // This WILL initialize to zero 
    ... 
} 

Mais les variables locales ne sont pas:

public static void SomeMethod() 
{ 
    int tmpCnt; // This is not initialized and must be assigned before used. 

    ... 
} 

Ainsi, votre code doit être:

int tmpCnt = 0; 
if (name == "Dude") 
    tmpCnt++; 

donc long et En bref, les membres sont initialisés, les locaux ne le sont pas. C'est pourquoi vous obtenez l'erreur du compilateur.

+4

Merci! Je ne connaissais pas la différence sur les membres et les sections locales +1 – theknut

+1

@James: savez-vous s'il s'agit simplement d'une fonctionnalité de compilation pour empêcher une telle erreur ou si le compilateur C# retarde réellement l'allocation de mémoire pour les locaux déclarés jusqu'à l'affectation? (Par exemple, en C++, l'utilisation d'une variable non assignée est "ok" même si la valeur d'une telle variable est imprévisible.) – ybakos

+2

Fonction de compilation pour éviter l'erreur. La mémoire (qui n'est bien entendu qu'une référence pour les types de référence) pour le local est allouée à la déclaration. –

0

Voir this thread concernant les boolos non-initialisés, mais il devrait répondre à votre question.

Les variables locales ne sont initialisées que si vous appelez leurs constructeurs (nouveau) ou si vous leur attribuez une valeur.

0

Les variables locales ne sont pas automatiquement initialisées. Cela ne se produit qu'avec des variables au niveau de l'instance.

Vous devez initialiser explicitement les variables locales si vous souhaitez les initialiser. Dans ce cas, (comme l'explique la documentation liée), soit en définissant la valeur 0, soit en utilisant l'opérateur new.

Le code que vous avez montré tente en effet d'utiliser la valeur de la variable tmpCnt avant d'être initialisée à quoi que ce soit, et le compilateur l'avertit à juste titre.

0

La table de valeurs par défaut s'applique uniquement à l'initialisation d'une variable.

par la page liée, les deux méthodes d'initialisation suivantes sont équivalentes ...

int x = 0; 
int x = new int(); 

Dans votre code, vous simplement défini la variable, mais jamais initialisées l'objet.

10

Les affectations par défaut s'appliquent aux membres de classe, mais pas aux variables locales. Comme Eric Lippert l'a expliqué dans this answer, Microsoft pourrait avoir locals initialisés par défaut, mais ils choisissent de ne pas le faire parce que l'utilisation d'un local non assigné est presque certainement un bug.

1

Alors que les types de valeur ont des valeurs par défaut et ne peuvent pas être nulles, ils doivent également être explicitement initialisés pour être utilisés. Vous pouvez considérer ces deux règles comme des règles côte à côte. Les types de valeur NE PEUVENT PAS être NULL ==> le compilateur garantit que. Si vous demandez comment? le message d'erreur que vous avez est la réponse. Une fois que vous appelez leurs constructeurs, ils sont inialisés avec leurs valeurs par défaut.

int tmpCnt; // not accepted 
int tmpCnt = new Int(); // defualt value applied tmpCnt = 0 
5

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

  • variables d'instance des variables struct initialement non attribuées.
  • Paramètres de sortie, y compris la variable this des constructeurs d'instance struct.
  • Variables locales, à l'exception de celles déclarées dans une clause catch ou une instruction foreach.

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

  • variables statiques.
  • Variables d'instance d'instances de classe.
  • Variables d'instance des variables struct initiales.
  • Éléments de tableau.
  • Paramètres de valeur.
  • Paramètres de référence.
  • Variables déclarées dans une clause catch ou une instruction foreach.
0

Les variables locales n'ont pas de valeur par défaut.

Ils doivent être définitivement assignés avant de les utiliser. Cela réduit les chances d'utiliser une variable dont vous pensez avoir donné une valeur raisonnable, alors qu'en réalité, elle a une valeur par défaut.

Questions connexes