2010-11-24 39 views
7

En C# 3.0, vous pouvez affecter null à int? Type (? en int CLR est un struct):Type de valeur C# initialisé avec null

int? a = null; 

mais lorsque vous définissez une structure personnalisée:

struct MyStruct 
{ 

} 

il y a une erreur lors de la compilation de ce code:

MyStruct a = null; 

L'erreur est la suivante:

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

Alors qu'int? est une structure dans CLR il est en quelque sorte contre-intuitif que nous pouvons assigner null à elle. Je suppose que null est implicitement cast ou encadré à un int de certian? valeur qui représente la valeur nulle. Comment est-ce fait précisément? Comment puis-je prolonger MyStruct de telle sorte qu'il serait possible d'exécuter la ligne:

MyStruct a = null; 

Répondre

19

C'est parce que int? est en fait un raccourci Nullable<int>. Vous pouvez faire la même chose pour votre type aussi:

MyStruct? a = null; 

null ne peut être converti implicitement à un type annulable, ce qui signifie tout type de référence ou tout autre type de valeur nullable - lorsque ces derniers moyens Nullable<T> pour certains T .

Notez que cette capacité à conver de null est vraiment une caractéristique de langue - le compilateur convertit ceci:

int? a = null; 

dans

int? a = new int?(); 

Ils signifient la même chose - en fait un " La valeur "null" pour un type de valeur NULL est une valeur où HasValue est false, ce qui sera le cas par défaut. Ce n'est pas la même chose qu'une référence null - bien que l'insertion d'une valeur nulle comme entraînera une référence nulle.

(Ceci est un exemple d'une fonctionnalité qui croise les limites de langage, de bibliothèque et de CLR.La partie bibliothèque est assez simple, la partie CLR concerne uniquement la boxe et le déballage - mais il y a beaucoup d'opérateurs levés etc dans le langage.)

+0

Moment intéressant de cette question. Je viens de finir de lire le chapitre sur les types nullables dans le livre de Jon (C# en profondeur). Chaque développeur C# devrait le lire !! Merci Jon. – Bryan

+0

Je voudrais juste souligner que je n'ai pas payé pour ce commentaire :) –

+0

Votre instruction "Notez qu'il s'agit vraiment d'une fonctionnalité de langue" est quelque peu déroutante puisque le CLR * fait * (comme vous le mentionnez plus tard) gérer 'Nullable <>' structs spécialement dans les opérations de boxe et de déballage, qui à mon humble avis en fait une fonctionnalité d'exécution (avec un peu de sucre syntaxique «?» Pour couronner le tout). – Lucero

2

Les structures sont des types de valeurs en C#, et non des types de références, donc elles ne peuvent pas être nulles.

MyStruct? = null; 

fonctionnera, mais rappelez-vous que struct sont immuables, comme par exemple:

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

Bien 'MyStruct?' Est toujours un type de valeur - mais il peut * être * nul. –

+3

Et toutes les structures ne sont pas immuables (malheureusement). –

+0

@Jon: Je pensais que les structures étaient passées en valeur, comment ne peuvent-elles pas être immuables? –

1

vient d'ajouter, un type nullable peut représenter la plage normale de valeurs pour son type de valeur sous-jacente, plus un montant supplémentaire valeur nulle.

En notation, tout comme int est réellement Int32, pas d'int, le? signe signifie nullable. Nullable, dans ce cas.

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