2008-12-29 15 views
5

Estaba hablando con un compañero de trabajo y surgió el tema de null. Me estaba diciendo que en .NET detrás de escena es solo un número realmente pequeño. Siempre pensé que el objeto simplemente no tenía un puntero a ninguna memoria en el montón, pero no estaba seguro de ninguna manera.¿Cómo se representa null en .NET

así que espero que la comunidad puede aclararlo para nosotros; P

Respuesta

5

Cuando una instancia de tipo anulable se establece en nulo, su valor subyacente es cero.

Para ser más específicos, un tipo que admite nulos es una estructura que combina un valor del tipo subyacente junto con un indicador nulo booleano. Una instancia de un tipo anulable tiene dos propiedades públicas de solo lectura: HasValue de tipo bool, y Valor del tipo subyacente del tipo anulable.

HasValue es verdadero para una instancia no nula y falso para una instancia nula.

Así que cuando HasValue es cierto, el propiedad valor Devuelve el valor contenido. Cuando HasValue es falso, un intento de acceder a la propiedad Value arroja una excepción. Pero si pudiera acceder a él, encontraría que contiene cero.

+0

Impresionante, esto es exactamente lo que estoy buscando. – Alex

+0

Esto es todo sobre 'Nullable ' - es * no * sobre referencias nulas. –

+0

@Jon, ¿está diciendo que mi uso de la palabra "instancia" es impreciso? – RoadWarrior

0

desde mi experiencia, creo que Nothing va a funcionar, y también lo hará DBNull.Value

+0

... Y simplemente lo malentendí por completo. Creo que Null o 'Nothing' son numéricamente equivalentes a cero, y almacenados como cualquier tipo de datos la variable que se le asignó – Sukasa

+0

Probablemente sea mejor simplemente eliminar la respuesta, de lo contrario obtendrás votos :) +1 por honestidad – leppie

+0

Y ahora ve la diferencia entre == y ===, intente comparar estos diversos tipos nulos. – TravisO

15

Es 0.

Recorte de ldnull dentro de las especificaciones ECMA-335:

podría pensarse que es ldnull redundante: ¿por qué no usar ldc.i4.0 o ldc.i8.0 en su lugar? La respuesta es que ldnull proporciona una nulidad independiente del tamaño - análoga a una instrucción ldc.i, que no existe. Sin embargo, incluso si CIL incluyera una instrucción ldc.i , aún se beneficiarían los algoritmos de verificación para retener la instrucción 0dldnull porque hace que el seguimiento de tipo sea más fácil.

+0

Realmente tengo que estar en desacuerdo con que null es 0 ... 0 es un valor ... null es un marcador de posición por la ausencia de una referencia a un objeto. Inicializar un objeto para que sea nulo y luego decir "oh, también es igual al valor 0" es un poco contradictorio en mi opinión – lomaxx

+1

@lomaxx - realmente es cero; esa es la forma en que se implementa a nivel CIL. Puedes pensar que es una dirección de memoria especial que se interpreta como nula. –

+1

@lomaxx: null es definitivamente un valor. Puedes hacer todo lo que puedas con otro valor: pasarlo, asignarlo a una variable, etc. Su * representación bit a bit * es todo ceros. –

-2

De MSDN:

la palabra clave NULL es un literal que representa una referencia nula, uno que no se refiere a ningún objeto

Para tratar de que sea un poco Más claro en las versiones anteriores de C#, un tipo de valor no podía ser nulo, es decir, TENÍA que tener un valor, si no asignaba uno, obtenía un valor potencialmente aleatorio, algo así como:

int i; 
i++; 
console.writeline(i); 

en las versiones anteriores de los objetos C# tenían que inicializarse, de lo contrario, eran nulas, lo que significaba que no tenían referencia a ningún objeto.

Ahora, con los tipos de valor que aceptan valores NULL en C# 2.0 + se puede tomar un int anulable lo que significa que si usted tiene este código:

int? i; 
i++; 
console.writeline(i); 

realidad se va a obtener una excepción en i ++ porque nunca se ha inicializado a cualquier cosa que no sea nulo. Si null era 0, este código se ejecutaría bien porque simplemente evaluaría a 0 + 1, sin embargo, este es un comportamiento incorrecto.

Si nula fue siempre 0, y ha tenido aa int anulable, y escribió algo de código como:

int? i; 
if (int == 0) 
{ 
//do something 
} 

hay una posibilidad muy real de que podría obtener un comportamiento inesperado SI nula fue el mismo que 0, porque no hay forma de que el compilador pueda diferenciar entre el int que es nulo y el int que se establece explícitamente en 0.

Otro ejemplo que aclara las cosas en mi mente:

public int? AddNumbers(int? x, int? y) 
{ 
    if (x == null || y == null) 
     return null; 
    if (x == 0) 
     return y; 
    if (y == 0) 
     return x; 

    return x + y; 
} 

en este ejemplo, está claro que nulo y 0 son muy diferentes porque si tuviera que pasar en 0 para X o Y, y nula fue igual a 0, entonces el código anterior nunca llegaría a los controles para x == 0 o y == 0, sin embargo, si ejecuta el código y pasa 0 para x o y, los controles se ejecutarán.

+0

No creo que esto ayude. El comportamiento de los operadores levantados tiene poco que ver con el valor subyacente de nulo. Y como sucede, el valor binario de un "nulo" Nullable * es * cero. Todos los ceros Entonces para int? es 5 ceros (uno para el indicador bool, 4 para el int). –

+0

(nota, el -1 no es de mí; prefiero retroalimentarlo a través de comentarios, no solo de votar a ciegas) –

+0

, pero si el valor de null * es * cero, ¿cuál es el valor de cero? ¿cómo se diferencia entre los dos? – lomaxx

Cuestiones relacionadas