9
votes

Pourquoi les types de référence ne sont-ils pas initialisés à NULL?

Vérifiez ce code ..

    string str = null;


0 commentaires

4 Réponses :


22
votes

Seuls les champs (variables déclarées au niveau de la classe) sont initialisés automatiquement:

  • Les types de valeur sont initialisés à leur valeur par défaut.
  • Les types de référence sont initialisés à null référence.

    Qu'est-ce que vous déclarez est une "variable locale" à l'intérieur d'une méthode. Les variables locales ne sont pas automatiquement initialisées, quel que soit leur type de valeur ou un type de référence.

    Je voudrais aussi savoir ce qui se passe pour le code ci-dessous. Comment fonctionne cette affectation?

    Cette affectation initialise la variable locale avec une valeur NULL avec une instruction ldnull suivie de l'instruction STLOC (au cas où il n'est pas optimisé, bien sûr) et plus important encore, et plus important encore, Satisfait les règles d'analyse des flux de données du compilateur pour une affectation définitive. C # Spécification Définit un concept appelé affectation définitive qui assure une variable est attribuée avant la première utilisation.


4 commentaires

Parlez-vous de champs qui sont des types de référence et toujours initialisés comme NULL? Alors pourquoi une telle différence?


Différence entre quoi? Être local ou non?


@Mehrdad: Je pense qu'il veut savoir pourquoi les variables locales ne sont pas automatiquement initialisées à leur valeur par défaut, par opposition aux champs. La raison en est que c'est déjà une optimisation. Le compilateur peut indiquer en toute sécurité si une variable locale est attribuée une valeur ou non. Si ce n'est pas le compilateur lancera une erreur lors de la compilation. Cette optimisation ne serait pas possible pour les champs.


Dans la perspective de la langue, cela vous aide à repasser peut-être des bugs pouvant causer à la suite de vous oublier l'initialisation. À partir du point de vue de l'exécution, lorsqu'il alloue une mémoire pour un objet sur le tas, il est zéros sur le bloc avant de la conserver pour éliminer le besoin d'initialisation manuelle.



-1
votes

Gardez à l'esprit également que l'appelant contient sur une chaîne nulle lancera une nullreferenceException.


1 commentaires

Je suppose que je manque compris. Je pensais que vous demandiez également ce qui se passerait si vous aviez le code définissant la variable STR à NULL. Dans ce cas, l'exception se produirait.



2
votes

It est-ce que est initialisé à NULL. Le compilateur vient de vous faire une faveur en ne faisant pas de déboguer la nullréférence inévitable que vous obtiendrez.


3 commentaires

Mehrdad a raison, les variables locales ne sont pas réellement initialisées, car elles seraient inutiles, car vous ne pouvez pas utiliser une variable locale tant qu'il n'est pas attribué une valeur, le compilateur ne vous laissera pas :-)


Hmya, problème de poulet et d'œuf. Il est autorisé dans vb.net, il ne génère aucun IL pour initialiser la variable locale. L'initialisation est effectuée par le compilateur JIT.


Lorsque vous changez au-dessus de l'exemple pour vérifier uniquement la chaîne pour NULL, vous ne pouvez toujours pas compiler car les Vares non initialisés ne peuvent même pas être vérifiés contre NULL. M'énerve parfois lors de la commutation entre C # et Java.



7
votes

Le C # Langauge nécessite que toutes les variables soient définitivement affectées avant leur lecture. Les variables locales sont considérées comme étant initialement non attribuées em>, tandis que les champs, les éléments de tableau, etc., sont considérés comme étant initialement attribués à leur valeur par défaut em>. (Qui, pour un type de référence, est NULL.)

Il n'y a pas de raison technique pour laquelle nous ne pouvions pas traiter les variables locales comme initialement affectées à leurs valeurs par défaut et jetez toute la vérification de l'affectation définitive. C'est là parce que l'utilisation d'une locale non attribuée comme valeur par défaut est (1) une mauvaise pratique de codage et (2) une source très probable d'insectes irritants. En vous demandant d'attribuer explicitement des variables locales avant qu'elles ne soient utilisées, nous empêchons l'utilisateur d'utiliser une mauvaise pratique et d'éliminer toute une classe de bugs que vous n'avez jamais à déboguer. P>

aussi, considérez les suivants : P>

while(whatever)
{
    int i;
    print(i);
    i = i + 1;
}


1 commentaires

Il convient de noter que si l'on changeait la ligne imprimer sur horsbject.print (sortie I); , appelant une routine écrite dans une autre langue, le compilateur générerait automatiquement un appel Pour vous assurer que i serait initialisé avant le premier appel, mais cela peut être initialisé ou non avant d'être initialisés avant les appels ultérieurs. En effet, si zz est un type de structure dont le constructeur passe ceci en tant que paramètre paramètre sur le code externe, même une instruction comme var foo = nouveau zz (2); pourrait ne pas laisser foo complètement intact.