2009-04-02 3 views
4

Ich frage mich, ob jemand weiß, wie der C# -Compiler folgende Zuordnung behandelt:Wie wird die Zuordnung des Null-Literals zu einem Typ System.Nullable <T> von .Net (C#) behandelt?

int? myInt = null; 

Meine Vermutung ist, dass es eine implizite Konvertierung durchgeführt ist, aber ich kann nicht herausfinden, wie die Null wörtliche Zuordnung behandelt wird. Ich Dissasembled die System.Nullable Objekt und fand die implizite Operator diese außer Kraft gesetzt wird:

public static implicit operator T?(T value) { 
    return new T?(value); 
} 

genannt Sobald dies versuchen würde, den sekundären Konstruktor Feuer:

public Nullable(T value) { 
    this.value = value; 
    this.hasValue = true; 
} 

das ist, wo meine Verwirrung ins Spiel kommt ... this.value ist von einem Werttyp und kann nicht null sein.

Also weiß jemand, wie diese "Magie" stattfindet ... oder bin ich falsch in der Annahme, dass der sekundäre Konstruktor aufgerufen wird? Wird der Standardkonstruktor aufgerufen, weil der Compiler weiß, dass er die Signatur des zweiten Konstruktors nicht mit dem Nullliteral abgleichen kann (was dazu führt, dass myInt einem neuen "Null" -Nullable zugewiesen wird)?

Antwort

8

Die Aussage:

int? myInt = null; 

kompiliert wird, wie:

.locals init (valuetype [mscorlib]System.Nullable`1<int32> V_0) 
    IL_0000: ldloca.s V_0 
    IL_0002: initobj valuetype [mscorlib]System.Nullable`1<int32> 

die, according to the MSDN bedeutet «Initialisieren jedes Feld des Werttyp an ein angegebene Adresse auf eine Nullreferenz oder eine 0 des entsprechenden Primitivtyps. »

Also gibt es hier keinen Konstruktor oder eine Konvertierung. HasValue gibt false zurück, und der Versuch, seinen Wert zu erhalten, löst eine InvalidOperationException aus. Es sei denn, Sie verwenden GetValueOrDefault natürlich.

+0

Dank Jb Evain, ich hätte gedacht, nach IL zu disassemblieren. –

0

Ich würde erwarten, .HasValue ist auf false eingestellt und .Value ist auf default(T) eingestellt, aber ich habe das nicht überprüft.

0

Etwas wie:

public Nullable() { 
    this.value = default(T); 
    this.hasValue = false; 
} 
3

Was wirklich passiert ist, dass, wenn Sie null zum Nullable-Typ-Instanz zuweisen, der Compiler einfach eine neue Instanz von T? erzeugt, die Standard-Konstruktor (die initobj IL Anweisung auf Jb answer), so dass die beiden folgenden Zeilen sind äquivalent:

int? a = null; 
Nullable<int> b = new Nullable<int>(); 

object.Equals(a,b); // true 

Daher können Sie dies nicht tun:

Nullable<int> c = new Nullable<int>(null); 

ähnlich Etwas passiert dann Sie eine Nullable Type auf null zu vergleichen:

if (a == null) 
{ 
    // ... 
} 

Hinter den Kulissen wird nur die a.HasValue-Eigenschaft aufgerufen.

-2

C# ist eine Hochsprache, die zu IL kompiliert wird.

Mit der Einführung von Nullable Types, der C# Standard geändert, so dass das Verhalten der C# Compiler mußte eine neue Regel zu behandeln ändern wie „keine Struktur, außer Nullable kann einen Wert von Null zugewiesen werden ".

Das Zuweisen von null zu einer Struktur ist im Allgemeinen nicht zulässig, aber das ist nur eine Regel, die der Compiler erzwingt, wenn das IL generiert. Da der Compiler all Ihren Code analysiert und herausfindet, was er bedeutet, kann er alle Arten von Regeln erkennen, sogar solche, die für Sie als Ausnahmen erscheinen mögen.

Wenn der Compiler Ihren C# -Code analysiert und feststellt, dass Sie einer Struktur null zuweisen, wird ein Fehler ausgegeben. Wenn es feststellt, dass Sie null einer Nullable<T> Struktur zuweisen, dann weiß es, wie man damit umgeht und erzeugt die passende IL.

Vom C# Standard:

13.7.1 Null type conversions:. „Eine implizite Konvertierung vom Null-Typ existiert (§11.2.7) an jedem Nullable Type Diese Umwandlung erzeugt den Nullwert (Kapitel 12.2) des NULL-Wert gegeben. "

12.2 Default values: „Der Standardwert eines Nullable Type ist eine Instanz, für die die HasValue Eigenschaft false ist Referenzierung der Value-Eigenschaft eines Standardwertes eines Nullable Types ergibt eine Ausnahme vom Typ System.InvalidOperationException Der Standard.. Der Wert wird auch als Nullwert des Nullable-Typs bezeichnet. Eine implizite Konvertierung besteht vom Null-Typ (§11.2.7) zu einem Nullable-Typ, und diese Konvertierung erzeugt den Nullwert des Typs. "

Verwandte Themen