2010-11-24 19 views
7

In C# 3.0 können Sie null zu int zuweisen? Typ (? in CLR int ist ein struct):C# -Wertyp initialisiert mit Null

int? a = null; 

aber wenn Sie eine benutzerdefinierte Struktur definieren:

struct MyStruct 
{ 

} 

gibt es einen Fehler bei der Erstellung dieses Codes:

MyStruct a = null; 

Der Fehler lautet wie folgt:

Cannot convert null to 'Example.MyStruct' because it is a non-nullable value type 

Während int? ist eine Struktur in CLR es ist irgendwie nicht intuitiv, dass wir ihm null zuweisen können. Ich nehme an, dass Null implizit Cassed oder Boxed zu einem certian int? Wert, der den Nullwert darstellt. Wie wird es genau gemacht? Wie kann ich MyStruct so erweitern, dass es möglich sein würde, die Zeile auszuführen:

MyStruct a = null; 

Antwort

19

Es ist, weil int? eigentlich eine Abkürzung Nullable<int> ist. Sie können für Ihre Art, die gleiche Sache tun zu:

MyStruct? a = null; 

null nur implizit in einen nullable Typen umgewandelt werden kann, was bedeutet, dass jeder Referenztyp oder einen Nullable-Wertetyp - wenn das letztgenannte Mittel Nullable<T> für einig T .

Beachten Sie, dass diese Fähigkeit von null conver ist wirklich eine Sprache Funktion - der Compiler dies konvertiert:

int? a = null; 

in

int? a = new int?(); 

Sie bedeuten die gleiche Sache - im Grunde ein " null "value für einen Nullwerttyp ist ein Wert, bei dem HasValue false ist, was standardmäßig der Fall ist. Es ist nicht das gleiche wie eine Null Referenz - obwohl Boxen einen Null-Wert wie das wird Ergebnis in einer Null-Referenz.

(Dies ist ein Beispiel für ein Feature, das Sprache, Bibliothek und CLR-Grenzen überschreitet. Der Bibliotheksteil ist ziemlich einfach, der CLR-Teil ist nur mit Boxen und Unboxing zu tun - aber es gibt eine Menge in Bezug auf angehobene Operatoren usw. in der Sprache.)

+0

Interessantes Timing dieser Frage. Ich habe gerade das Kapitel über Nullable-Typen in Jons Buch (C# in Depth) gelesen. Jeder C# Entwickler sollte es lesen !! Danke Jon. – Bryan

+0

Ich möchte nur darauf hinweisen, dass ich nicht für diesen Kommentar bezahlt habe :) –

+0

Ihre Aussage "Beachten Sie, dass dies wirklich eine Sprachfunktion ist" ist etwas verwirrend, da die CLR * (wie Sie später erwähnen) handelt 'Nullable <>' Strukturen speziell in Boxing und Unboxing-Operationen, die IMHO macht eine Laufzeit-Funktion (mit einigen '?' Syntaktischen Zucker, um es abzurunden). – Lucero

2

Strukturen sind Werttypen in C#, keine Referenztypen, daher können sie nicht null sein.

MyStruct? = null; 

funktionieren wird, aber denken Sie daran, dass structs unveränderlich sind, als Beispiel:

public struct Point 
{ 
    public int x, y; 

    public Point(int p1, int p2) 
    { 
     x = p1; 
     y = p2;  
    } 
} 

void Main() 
{ 

    //create a point 
    var point1 = new Point(10, 10); 

    //assign point2 to point, point2 
    var point2 = point1; 

    //change the value of point2.x 
    point2.x = 20; 

    //you will notice that point1.x does not change 
    //this is because point2 is set by value, not reference. 
    Console.WriteLine(point1.x); 
    Console.WriteLine(point2.x); 

} 
+1

Nun 'MyStruct?' Ist immer noch ein Werttyp - aber * kann * null sein. –

+3

Und nicht alle Strukturen sind unveränderlich (leider). –

+0

@Jon: Ich dachte, Strukturen wurden nach Wert übergeben, wie können sie nicht unveränderlich sein? –

1

gerade hinzufügen, ein Nullable Type den normalen Bereich von Werten für den zugrunde liegenden Werttyp darstellen kann, sowie eine zusätzliche Nullwert

In der Notation, genau wie int ist eigentlich Int32, nicht alle int, die? Zeichen bedeutet NULL-Wert. Nullable, in diesem Fall.

http://msdn.microsoft.com/en-us/library/1t3y8s4s%28VS.80%29.aspx

Verwandte Themen