web-dev-qa-db-fra.com

Correction de «l'utilisation de la variable locale non affectée» avec une affectation nulle. Pourquoi?

Avec un morceau de code comme celui-ci, le compilateur se plaint de c.MyProperty:

MyClass c;

try { throw new Exception(); }
catch (Exception) { }

c.MyProperty = 2; // "Use of unassigned local variable 'c'".

Pourtant, il ne se plaint pas si vous affectez un null à c lors de l'initialisation:

MyClass c = null;

try { throw new Exception(); }
catch (Exception) { }

c.MyProperty = 2; // no complains this time.

Alors, pourquoi ça marche? Si c ne se voyait pas attribuer un null et que le compilateur le permettait hypothétiquement, la même exception ne serait pas levée sur c.MyProperty, La référence d'objet n'est pas définie sur une instance d'un objet?

31
Andreas Grech

Lorsque vous affectez null à la variable, vous dites au compilateur de se retirer car vous le savez mieux que lui, il ne devrait donc pas s'en plaindre.

Cela est probablement dû au fait que l'attribution de null est considérée comme impliquant une action explicite du développeur.

66
João Angelo

Pensez-y de cette façon, le compilateur ne vous dit pas qu'il va jeter une référence nulle et donc qu'il ne peut pas compiler, mais plutôt que l'une des conditions n'est pas remplie qui sont nécessaires pour compiler, c'est-à-dire qu'il a être définitivement attribué.

Selon la spécification, null est un littéral c #: "Le littéral null peut être implicitement converti en un type de référence ou un type nullable"

Ainsi qu'en termes de missions: (tiré du cahier des charges)

Début du devis tiré de la spécification

5.3. Règles précises pour déterminer l'affectation définitive Afin de déterminer que chaque variable utilisée est définitivement affectée, le compilateur doit utiliser un processus équivalent à celui décrit dans cette section.

Le compilateur traite le corps de chaque membre de fonction qui a une ou plusieurs variables initialement non affectées. Pour chaque variable v non affectée initialement, le compilateur détermine un état d'affectation défini pour v à chacun des points suivants du membre de la fonction:

· Au début de chaque déclaration

· Au point final (§8.1) de chaque énoncé

· Sur chaque arc qui transfère le contrôle à une autre instruction ou au point final d'une instruction

· Au début de chaque expression

· À la fin de chaque expression

Fin du devis

Ainsi, même si null ne pointe pas réellement vers un objet en mémoire, il remplit les conditions requises pour être définitivement attribué et c'est pourquoi le compilateur le permet.

1
TBohnen.jnr

Cela est dû au fait que la spécification du langage C # v. 4.0 section 1.6.6.2 "Corps de méthode et variables locales" indique ce qui suit:

Un corps de méthode peut déclarer des variables spécifiques à l'appel de la méthode. Ces variables sont appelées variables locales.

[sauté]

C # nécessite qu'une variable locale soit définitivement attribuée avant que sa valeur puisse être obtenue.

C'est pour éviter de vous laisser vous tirer une balle dans le pied, comme l'a clairement souligné Binary Worrier.

1
Igor Korkhov

La raison de cette exception est que vous n'avez pas attribué de valeur par défaut à la variable, par exemple

if (Request.Files != null  && Request.Files.Count > 0)
            {
                 Image = Request.Files.AllKeys[0];
            }
var stream  = new FileStream(Image,FileMode.Open);

maintenant la variable Image donnera une erreur de compilation

Utilisation de la variable locale non affectée "Image"

Cela est dû à la raison pour laquelle il est possible que la condition devienne vraie et que le contrôle ne puisse jamais savoir ce qu'est la variable Image. placez donc un bloc else ou attribuez une valeur par défaut comme ci-dessous.

string Image = "";
if (Request.Files != null  && Request.Files.Count > 0)
            {
                 Image = Request.Files.AllKeys[0];
            }
var stream  = new FileStream(Image,FileMode.Open);
0
ImranNaqvi