¿Cuál es el valor predeterminado del tipo anulable "int"? (incluido el signo de interrogación)?

100

En C #, ¿cuál es el valor predeterminado de una variable de instancia de clase de tipo int??

Por ejemplo, en el siguiente código, ¿qué valor tendrá MyNullableIntsi nunca se asigna explícitamente?

class MyClass
{
    public int? MyNullableInt;
}

(Parece probable que la respuesta sea casi con certeza nullo 0, pero ¿cuál de ellos es?)

Jon Schneider
fuente
9
¿Por qué el voto negativo? (La respuesta a esta pregunta no fue inicialmente obvia para mí sin realmente ejecutar el código para probar el comportamiento; y sorprendentemente, no pude encontrar un duplicado de esta pregunta en StackOverflow, o fácilmente encontrable en otro lugar a través de Google)
Jon Schneider
1
Podrías haber mirado aquí : el primer resultado de Google para mí.
500 - Error interno del servidor
2
@ 500: encontré ese artículo cuando estaba investigando; de hecho, lo vinculé en mi propia respuesta a continuación, pero por lo que puedo decir, el artículo no indica explícitamente que el valor predeterminado de una instancia de tipo anulable es nulo. Que no dicen "El valor predeterminado para HasValue es falso. El valor de la propiedad no tiene valor por defecto", pero eso no responde directamente a mi pregunta original sin algo de investigación adicional.
Jon Schneider
2
Me pregunto si fue porque simplemente pudo establecer un punto de interrupción y ver cuál es el valor, o en el tipo de Ventana Inmediato int? x;y ver cuál es el resultado.
Rufus L

Respuestas:

135

El valor predeterminado para int?- y para cualquier tipo que acepte valores NULL que use "type?" declaración - es null.

Por qué este es el caso:

  • int?es azúcar sintáctico para el tipo Nullable <T> (donde T es int), una estructura. ( referencia )
  • El Nullable<T>tipo tiene un miembro bool HasValue , que cuando falsehace que la Nullable<T>instancia "actúe como" un nullvalor. En particular, el Anulable <T> método .equals se anula para volver truecuando una Nullable<T>con HasValue == falsese compara con un actual nullvalor.
  • De la Especificación del lenguaje C # 11.3.4 , el valor predeterminado inicial de una instancia de estructura son todos los campos de tipo de valor de esa estructura establecidos en su valor predeterminado, y todos los campos de tipo de referencia de esa estructura configurados en null.
  • El valor predeterminado de una boolvariable en C # es false ( referencia ). Por lo tanto, la HasValuepropiedad de una Nullable<T>instancia predeterminada es false; lo que a su vez hace que esa Nullable<T>instancia actúe como null.
Jon Schneider
fuente
Cuando cambio una declaración de int? x = null;a int? x;, obtengo errores del compilador más abajo en el código: "Uso de la variable local x no asignada".
John Pick
1
@JohnPick Esa es una característica del compilador de C # destinada a evitar errores que puedan surgir si usted "olvida" inicializar una variable antes de usarla. ¿Una situación en la que puede encontrar un int no inicializado? es cuando es una variable miembro de clase. Ejemplos de ambos aquí: blogs.msdn.microsoft.com/abhinaba/2005/11/08/…
Jon Schneider
Entonces, ¿básicamente este lugar es tu blog de tecnología? Hace preguntas para las que solo necesita ejecutar el código para obtener la respuesta, luego responde la pregunta usted mismo en el mismo minuto.
GôTô
4
@JonSchneider bastante justo, mi mal entonces
GôTô
Compilador de pista / advertencia de VS es engañoso: Field 'id' is never assigned to, and will always have its default value 0. Extraño, ¿no?
Hendy Irawan
30

Me sentí importante compartir el Nullable<T>.GetValueOrDefault()método que es particularmente útil cuando se trabaja con cálculos matemáticos que usan valores de Nullable<int>aka int?. Hay muchas ocasiones en las que no tiene que verificar la HasValuepropiedad y puede usarla GetValueOrDefault()en su lugar.

var defaultValueOfNullableInt = default(int?);
Console.WriteLine("defaultValueOfNullableInt == {0}", (defaultValueOfNullableInt == null) ? "null" : defaultValueOfNullableInt.ToString());

var defaultValueOfInt = default(int);
Console.WriteLine("defaultValueOfInt == {0}", defaultValueOfInt);

Console.WriteLine("defaultValueOfNullableInt.GetValueOrDefault == {0}", defaultValueOfNullableInt.GetValueOrDefault());

Línea de comando que muestra el código de arriba funcionando

Brian Ogden
fuente
0
var x = default (int?);
Console.WriteLine("x == {0}", (x == null) ? "null" : x.ToString());
Rufus L
fuente