2012-06-03 8 views
5

Ich versuche, eine Sache in diesem Code zu verstehen:Wie kann CLR den Wurffehler umgehen, wenn der Struktur ein Nullwert zugewiesen wird?

Nullable<Int32> x = 5; 
Nullable<Int32> y = null; 
Console.WriteLine("x: HasValue={0}, Value={1}", x.HasValue, x.Value); 
Console.WriteLine("y: HasValue={0}, Value={1}", y.HasValue, y.GetValueOrDefault()); 

und Ausgang ist:

x: HasValue=True, Value=5 
y: HasValue=False, Value=0 

Und die Sache, die ich nicht verstehe, wenn Sie null zu y passieren, ich glaube, es ruft public static implicit operator Nullable<T>(T value) auf, aber die Definition dieser Methode initialisiert eine neue Struktur, die value übergibt, die null zugewiesen wird, jedoch überprüft die Konstruktormethode nicht, ob es null ist oder nicht, sodass default(T) zuzugewiesen werden kann.

Wie können wir hier sogar null zu struktur zuweisen und es funktioniert gut?

Können Sie Leute, die ich hier verpasse? Ich verstehe nicht, wie es null umgangen und den Standardwert zurückgegeben.

Nullable Code innere Definition:

http://codepaste.net/gtce6d

+0

ein Grund, warum Sie verwenden nicht die eingebaute 'Nullable ' struct? –

+0

Ich lerne gerade die interne Struktur der Nullable-Typen. – Tarik

+0

Als eine Nebenbemerkung: Ihre 'Equals' Implementierung ist gebrochen.Wenn beide Seiten sind Ihre benutzerdefinierte Nullable, und beide sind custom-null, es gibt false zurück, sollte aber true zurückgeben. | Es sollte auch nicht kompiliert werden, da Sie keine Initialisierer für Instanzfelder für Strukturen haben können. – CodesInChaos

Antwort

6

glaubt, es ruft öffentlichen statischen impliziten Operator Nullable (T genannt Konstruktor zugeordnet ist Wert)

Nr nicht, weil T in diesem Fall Int32 ist und null kein Int32 ist. Es lässt nur die Variable y Variable, die für eine Struktur bedeutet, dass alle Bytes 0 sind. Dies führt zu einer Struktur, die eine HasValue hat, die false zurückgibt.

Sie können null nicht wirklich an eine Struktur übergeben, aber der C# -Compiler wandelt dies für Sie in eine Standardinitalisierung um.

+0

Was macht dann diese Struktur "Nullable" und "Int32" nicht? Wie kommt es, dass Sie 'null' zuweisen können, was noch keinen Fehler auslöst?' Int32' tut das? Weil es "implizites" Überladen hat? – Tarik

+0

Und yeah Ich setzte eine Struktur eine Null und es war ein Fehler: http://ideone.com/NIbfn – Tarik

+2

Was macht es Nullable ist, dass Sie definiert ist bei Nullable . Nullable Struktur hat einige Compiler Magie, um es einfacher zu verwenden. – TomTom

1

Der Standard in dem von new Nullable<T>(value); (Linie 40)

+0

Aber wie können wir eine Null an die Struktur übergeben? – Tarik

1

Meine Vermutung ist, dass die Zuweisung null zu einem Nullable den Standardkonstruktor aufruft. Nur so kann hasValuefalse bleiben.

+0

Können sie keine 'if'-Anweisungen haben, um zu überprüfen, ob sie die HasValue-Eigenschaft ändern sollen? – SimpleVar

+0

@YoryeNathan könnten sie vielleicht, aber es gibt keine. tatsächlich, obwohl es nicht "readonly" auf den Feldern sagt, ist die Struktur entworfen, um unveränderlich zu sein. hasValue und value werden beide nur in Konstruktoren gesetzt; also ja, während es im Code nicht gezeigt wird, ist der Standardkonstruktor die einzige Möglichkeit, einen Wert von "null" zu erhalten. –

+0

Aber 'struct' kann keinen parameterlosen Konstruktor haben. Wie kommt es heißt es? http://StackOverflow.com/Questions/575901/Why-Struct-Can-Not-Have-Parameterless-Constructor – Tarik

1

Eine Nullable<T> ist einfach eine Struktur, die ein boolesches Feld hat, das angibt, ob es einen Wert hat, und ein Feld, das (wenn das erste Feld wahr ist) angibt, was dieser Wert ist. Es ist nicht wirklich möglich, eine Struktur auf null zu setzen, und eine Nullable<T> ist keine Ausnahme. Stattdessen übersetzt der Compiler eine Anforderung zum Setzen einer Nullable<T> auf null als Anforderung, das Feld "has value" (reflektiert in der Eigenschaft HasValue) auf false zu setzen und das Feld "actual value" (reflektiert in der Eigenschaft Value) auf den Standardwert für zu setzen sein Typ.

Ich persönlich denke, so zu tun, dass ein Nullable<T> wo HasValue falsch ist null als hilfreich mehr verwirrend ist, aber ich bin nicht Microsoft.Ich würde denken, es wäre hilfreich gewesen, mehr hat für jeden Nullable<T> Typen eine statische Eigenschaft haben Nullable<T>.Null (die default(Nullable<T>) entsprechen würde, aber das Verhalten von Nullable<T> ist ausreichend gut etablierte ich bezweifle, dass es jemals ändern.