2012-06-03 10 views
5

estoy tratando de entender una cosa en este código:¿Cómo puede CLR omitir el error de lanzamiento al asignar un valor nulo a la estructura?

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()); 

y la salida es:

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

Y lo que no entiendo cuando se pasa a nully, creo que llama a public static implicit operator Nullable<T>(T value) pero la definición de este método inicializa una nueva estructura que pasa value que está asignada null, pero el método constructor no verifica si es nula o no, por lo que puede asignar default(T) a .

¿Cómo es que incluso podemos asignar null a struct aquí y funciona bien?

¿Pueden chicos lo que me estoy perdiendo aquí? No entiendo cómo pasó por alto null y devolvió el valor predeterminado.

código anulable definición interna:

http://codepaste.net/gtce6d

+0

ninguna razón por la cual usted no está usando el construido en 'Nullable ' struct? –

+0

Estoy aprendiendo la estructura interna de los tipos que aceptan nulos. – Tarik

+0

Como nota al margen: Su implementación 'Igual' está rota. Si ambos lados son su nulo personalizado, y ambos son custom-null, devolverá false, pero debería devolver true. | Tampoco debería compilar, porque no puede tener inicializadores en campos de instancia para estructuras. – CodesInChaos

Respuesta

6

creen que llama operador implícita public static anulable (T valor)

No no lo hace, porque T es Int32 en este caso, y null no es Int32. Solo deja la variable y predeterminada, lo que significa que para una estructura todos los bytes son 0. Esto da como resultado una estructura que tiene un HasValue que devuelve false.

No se puede pasar realmente null a una estructura, pero el compilador de C# está convirtiendo esto para su inicialización predeterminada.

+0

Entonces, ¿qué hace que esta estructura 'Nullable' y' Int32' no? ¿Cómo puede asignar 'null' que no arroja un error pero' Int32' sí? ¿Es porque tiene una sobrecarga 'implícita '? – Tarik

+0

Y sí, configuré una estructura nula y arrojó un error: http://ideone.com/NIbfn – Tarik

+2

Lo que lo hace anulable es que tu definido está en nullable . Nullable struct tiene algo de compilación mágica detrás para que sea más fácil de usar. – TomTom

1

El valor por defecto se le asigna en el constructor llamado por new Nullable<T>(value); (línea 40)

+0

Pero, ¿cómo es que podemos pasar un nulo a la estructura? – Tarik

1

Supongo que al asignar null a un valor nulo se llama al constructor predeterminado. Esa es la única forma posible de que hasValue permanezca en false.

+0

¿No pueden tener algunas declaraciones 'if' para comprobar si deberían cambiar la propiedad HasValue? – SimpleVar

+0

@YoryeNathan tal vez podrían, pero no hay ninguno. de hecho, aunque no dice 'readonly' en los campos, la estructura está diseñada para ser inmutable. hasValue y value solo se establecen en constructores; así que sí, aunque no se muestra en el código, el constructor predeterminado es la única forma de obtener un valor de 'null'. –

+0

Pero 'struct' no puede tener constructor sin parámetros. ¿Cómo es que lo llama? http://stackoverflow.com/questions/575901/why-struct-can-not-have-parameterless-constructor – Tarik

1

A Nullable<T> es simplemente una estructura que tiene un campo booleano que indica si tiene un valor, y un campo que (si el primer campo es verdadero) indica cuál es ese valor. No es posible establecer ninguna estructura en null, y Nullable<T> no es una excepción. En su lugar, el compilador traduce una solicitud para establecer Nullable<T> en null como una solicitud para establecer el campo "tiene valor" (reflejado en la propiedad HasValue) en falso y establecer el campo "valor real" (reflejado en la propiedad Value) en el valor predeterminado su tipo.

personalmente, creo que pretender que un Nullable<T> donde HasValue es falso es null es más confuso que útil, pero no estoy Microsoft.Yo creo que habría sido más útil para cada tipo Nullable<T> que tiene una propiedad estática Nullable<T>.Null (lo que equivaldría a default(Nullable<T>), pero el comportamiento de Nullable<T> es lo suficientemente bien establecida Dudo que alguna vez va a cambiar.

Cuestiones relacionadas