2010-11-24 9 views
7

En C# 3.0, ¿puede asignar null a int? Tipo (? en int CLR es un struct):Tipo de valor de C# inicializado con nulo

int? a = null; 

pero cuando se define una estructura personalizada:

struct MyStruct 
{ 

} 

hay un error durante la compilación de este código:

MyStruct a = null; 

El error es el siguiente:

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

Mientras int? es una estructura en CLR, de alguna manera es contradictorio que podamos asignarle nulo. Supongo que null está implícitamente casted o en caja a un certian int? valor que representa el valor nulo. ¿Cómo se hace exactamente? ¿Cómo puedo extender MyStruct de tal manera que sería posible ejecutar la línea:

MyStruct a = null; 

Respuesta

19

Es porque int? es en realidad la abreviatura Nullable<int>. Puede hacer lo mismo para su tipo también:

MyStruct? a = null; 

null Sólo se puede convertir implícitamente a un anulable tipo, lo que significa que cualquier tipo de referencia o cualquier tipo de valor anulable - en donde los últimos medios Nullable<T> por alguna T .

Tenga en cuenta que esta capacidad de conver de null es realmente una característica lenguaje - el compilador es convertir esto:

int? a = null; 

en

int? a = new int?(); 

que significan la misma cosa - básicamente un " valor nulo "para un tipo de valor que admite nulos es un valor donde HasValue es falso, que será por defecto. No es lo mismo que una referencia nula - aunque un valor nulo en el box como el dará como resultado una referencia nula.

(Este es un ejemplo de una característica que cruza fronteras de lenguaje, biblioteca y CLR. La parte de la biblioteca es bastante simple, la parte CLR solo tiene que ver con boxeo y unboxing, pero hay bastante en términos de operadores levantados etc. en el idioma.)

+0

Tiempos interesantes de esta pregunta. Acabo de terminar de leer el capítulo sobre tipos anulables en el libro de Jon (C# en profundidad). ¡Cada desarrollador de C# debería leerlo! Gracias Jon. – Bryan

+0

Simplemente me gustaría señalar que no pagué ese comentario :) –

+0

Su afirmación "Tenga en cuenta que esto es realmente una característica de idioma" es algo confuso ya que CLR * lo hace * (como usted menciona más adelante) manejarlo 'Nullable <>' estructura especialmente en las operaciones de boxeo y desembalaje, lo que en mi humilde opinión hace de esto una característica de tiempo de ejecución (con algo de azúcar sintáctico '?' Para colmo). – Lucero

2

Las estructuras son tipos de valores en C#, no tipos de referencia, por lo que no pueden ser nulas.

MyStruct? = null; 

funcionará, pero recuerda que las estructuras son inmutables, como un ejemplo:

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

Bueno 'MyStruct?' Sigue siendo un tipo de valor, pero * puede * ser nulo. –

+3

Y no todas las estructuras son inmutables (por desgracia). –

+0

@Jon: Pensé que las estructuras se pasaban por valor, ¿cómo no pueden ser inmutables? –

1

limitarse a añadir, un tipo anulable puede representar el rango normal de valores para su tipo de valor subyacente, más un adicional valor nulo.

En notación, al igual que int es en realidad Int32, no int, el? signo significa un nulo. anulable, en este caso.

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

Cuestiones relacionadas