Correction de l '"utilisation de la variable locale non assigné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
en initialisation:
MyClass c = null;
try { throw new Exception(); }
catch (Exception) { }
c.MyProperty = 2; // no complains this time.
Alors, pourquoi cela fonctionne-t-il? Si c
n'était pas assigné à null
et que le compilateur l'autorisait hypothétiquement, la même exception ne serait-elle pas lancée c.MyProperty
, référence D'objet non définie sur une instance d'un objet?
4 réponses
Lorsque vous affectez null
à la variable, vous dites au compilateur de reculer parce que vous le savez mieux que lui, donc il ne devrait pas se plaindre à ce sujet.
Ceci est probablement dû au fait que l'affectation de null
est considérée comme impliquant une action explicite du développeur.
Pensez-y de cette façon, le compilateur ne vous dit pas qu'il va lancer une référence nulle et donc il ne peut pas compiler, mais plutôt qu'une des conditions requises pour compiler n'est pas remplie, c'est-à-dire qu'il doit être définitivement assigné.
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 d'affectations: (tiré de la spécification)
Début de citation tirée de la spécification
5.3.3 règles précises pour déterminer l'affectation définie Afin de déterminer que chaque variable utilisée est définitivement assigné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 initialement non assignée v, le compilateur détermine un État d'affectation défini pour v à chacune des variables suivantes: les points suivants dans le membre de la fonction:
· Au début de chaque instruction
· au point final (§8.1) de chaque déclaration
* 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 de citation
Donc, même si null ne pointe pas réellement vers un objet en mémoire, elle remplit les exigences d'être définitivement attribué, et c'est pourquoi le compilateur permet.
Ceci est dû au fait que la section 1.6.6.2 "corps de la méthode et variables locales" de la spécification du langage C# v. 4.0 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.
[ignoré]
C # nécessite qu'une variable locale soit définitivement assignée avant que sa valeur puisse être obtenue.
C'est pour éviter de vous laisser tirer dans le pied, comme Worrier binaire soigneusement souligné.
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 l'erreur du compilateur
Utilisation de la variable locale non affectée 'Image'
Cela est dû à la raison qu'il est possible que la condition devienne vraie et que le contrôle n'apprenne jamais à connaître la variable D'Image . donc, placez 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);