fait null code> a un type? Comment une valeur nulle est-elle représentée en interne? Ce qui se passe dans le code suivant? void Foo(string bar) {...}
void Foo(object bar) {...}
Foo((string)null);
7 Réponses :
Il appellera FOO (barre de cordes). P>
Vous pouvez lancer Null Fine. P>
Le mot clé NULL est un littéral qui représente une référence nulle, une référence qui ne fait référence à aucun objet. NULL est la valeur par défaut des variables de type de référence. De MSDN . Donc, la valeur par défaut de la chaîne dans votre exemple. Ce que vous faites est équivalent à l'utilisation par défaut selon ci-dessus: P>
int equal = string.Compare((string)null, default(string));
Lorsque vous définissez un objet de référence sur Comme démontré par d'autres (1) (2) , cela ne semble pas Soyez le cas car le compilateur résout la surcharge émettant de l'IL selon le Je sais que les variables de référence ont un type associé à eux. Je pensais que cela serait derrière ce the null code>, le pointeur (derrière) pointe sur un endroit spécial en mémoire désigné null code>. Alors, lorsque vous lancez sur null code>, vous créez vraiment un pointeur du type spécifique qui pointe vers null code>. s> p> p>
NULL CODE> NULL P>
null code> casting mais j'avais tort. P>
ldnull code> opcode pousse une référence nulle (type O) sur la pile. Et même si cette référence nulle a un type associé à celui-ci, le appel code> accepte cette référence comme argument valide de chaîne code>. Au moins, c'est ma compréhension. Si quelqu'un a des corrections à cela, n'hésitez pas à me corriger. P>
La distribution à Qu'est-ce que la distribution est indiquée au compilateur qui surcharge à choisir. Comme Si vous voulez voir ce qui se passe en dessous, puis regardez le Il de votre code. Le bit pertinent pour l'appel de la méthode est quelque chose comme les éléments suivants dans Textual IL (en fonction de votre espace de noms et de votre nom de classe, etc.): p> donc tout ce qui se passe est qu'un null est chargé sur la pile, puis celui-ci est consommé par la surcharge qui prend la chaîne, car la résolution de surcharge est effectuée au moment de la compilation afin que la méthode appelle soit cuite à l'IL. P> Si vous voulez Voir ce que String code> dans votre exemple exemple ne donne pas le type code> null code> un type, comme null code> ne peut pas avoir de type lui-même. Si vous souhaitez la preuve, alors exécutez le code suivant où vous pouvez voir que null code> est toujours égal à lui-même, quel que soit le type de variable qu'il a été attribué est: null code> n'a pas de type, il ne sait pas s'il faut choisir la surcharge qui prend un objet objet code> ou a chaîne code> car la valeur pourrait être la valeur. interprété comme non plus. Donc, vous l'aidez en disant «Voici une valeur nulle qui devrait être traitée comme si c'était une chaîne». P>
ldnull code> fait et pourquoi il est différent de simplement utiliser quelque chose comme ldc.i4.0 code> pour charger un zéro sur la pile, puis voir Cette réponse (Si vous ne voulez pas suivre le lien, la raison est que c'est un taille-agnostic zéro qui n'existe autrement pas dans le CLR). p> p>
Alors, que sera exactement sur la pile lorsque je parle de null code>?
@Matt - édité pour ajouter plus de détail de bas niveau. Est-ce suffisant?
@Greg: Merci - j'étais occupé au travail alors n'avait pas le temps de vérifier l'IL et l'ECMA SPEC-moi-même. Cela a gratté ma démangeaison intellectuelle.
null est un marqueur, il n'a pas de type de données.Lors que vous attribuez .NULL à un champ ou à une variable, la valeur change sur NULL, mais le type de données du champ ou de la variable ne change pas. P>
La raison de l'attribution de type de chaîne à NULL dans votre exemple, je pense que la méthode de la sorcière sera utilisée (dans ce cas "Void FOO (String Bar) {...}" Parce que c'est la méthode qui accepte cordes comme arguments.) p>
Si vous auriez appelé foo ((objet) null); L'autre méthode aurait été utilisée. ("Void Foo (Object Bar) {...}") P>
NULL n'a pas de type, et "et" et dans l'extrait de code, est le casting utilisé simplement par le compilateur C # pour décider quelle surcharge à appeler, et il n'y a pas vraiment de casting de NULL? " est exactement ce qui se passe. Regardons l'IL généré.
IL_0001: ldnull IL_0002: call void ConsoleApplication1.Program::Foo(object)
Le type de la valeur 11.2.7 Le type NULL P>
Le littéral null (§9.4.4.6) évalue à la null
valeur, qui est utilisée pour désigner un
Référence ne pointant sur aucun objet
ou une matrice ou l'absence d'une valeur.
Le type null a une valeur unique,
qui est la valeur null. D'où un
expression dont le type est le type null
peut évaluer uniquement la valeur null.
Il n'y a aucun moyen d'écrire explicitement
le type nul et, donc, aucun moyen
pour l'utiliser dans un type déclaré. P>
blockQuote>
Le type NULL est le type inférieur de la hiérarchie de type - l'opposé de l'objet; Le type NULL peut être considéré comme étant un sous-type de type nullable, car la valeur null peut être utilisée partout où une expression nullable se produit. p>
Cela crée une faiblesse dans le système de type, car cela signifie que toute opération dont le récepteur est un type nullable pourrait être null, et l'opération peut échouer au moment de l'exécution d'une exception. Dans un système de type solide, les opérations fournies par un type sont garanties si le récepteur est de ce type (c'est-à-dire que vous ne recevriez pas une exception de pointeur NULL, qui dit vraiment que le type null ne met pas en œuvre la méthode que vous avez Invoqué dessus, bien que la valeur nulle puisse résulter de l'expression de tout type que vous pensiez utiliser). p>
Dans votre code, les méthodes sont surchargées et le type statique de l'expression produisant l'argument est utilisé pour la résolution de la surcharge. En raison de la fonte à la chaîne, l'expression a une chaîne de caractères (le type NULL étant un sous-type de chaîne ceci est à la hausse si sûre selon le système de type C #). En première approximation, le compilateur sélectionne la surcharge la plus spécifique visible, donc chose la version de chaîne de null code> est défini par ECMA-334 comme suit: P>
FOO code> plutôt que la version d'objet. p>