Qual é o valor padrão do tipo anulável “int?” (incluindo ponto de interrogação)?

100

Em C #, qual é o valor padrão de uma variável de instância de classe do tipo int??

Por exemplo, no código a seguir, qual valor terá MyNullableIntse nunca for atribuído explicitamente?

class MyClass
{
    public int? MyNullableInt;
}

(Parece provável que a resposta seja nullou 0, mas qual é?)

Jon Schneider
fonte
9
Por que o downvote? (A resposta a esta pergunta não foi inicialmente óbvia para mim sem realmente executar o código para testar o comportamento; e, surpreendentemente, não consegui encontrar uma duplicata desta pergunta no StackOverflow ou facilmente encontrada em outro lugar pelo Google.)
Jon Schneider
1
Você poderia ter olhado aqui - primeiro hit do google para mim.
500 - Erro interno do servidor,
2
@ 500 - Encontrei esse artigo quando estava pesquisando - na verdade, vinculei a ele em minha própria resposta abaixo - mas, pelo que posso dizer, o artigo não afirma explicitamente que o valor padrão de uma instância de tipo anulável é nulo. Ele não dizer "O valor padrão para HasValue é falsa. O valor da propriedade não tem valor padrão", mas que não responde diretamente a minha pergunta original sem alguma escavação adicional.
Jon Schneider
2
Eu me pergunto se foi porque você poderia apenas definir um ponto de interrupção e ver qual é o valor, ou no tipo Janela Imediata int? x;e ver qual é o resultado?
Rufus L

Respostas:

135

O valor padrão para int?- e para qualquer tipo anulável que usa o "tipo?" declaração - é null.

Por que este é o caso:

  • int?é um açúcar sintático para o tipo Nullable <T> (onde T é int), uma estrutura. ( referência )
  • O Nullable<T>tipo tem um membro bool HasValue que false, quando , faz com que a Nullable<T>instância "aja como" um nullvalor. Em particular, o método Nullable <T> .Equals é sobrescrito para retornar truequando um Nullable<T>with HasValue == falseé comparado com um nullvalor real .
  • A partir da Especificação de linguagem C # 11.3.4 , o valor padrão inicial de uma instância de struct são todos os campos de tipo de valor dessa estrutura definidos como seu valor padrão e todos os campos de tipo de referência dessa estrutura definidos como null.
  • O valor padrão de uma boolvariável em C # é false ( referência ). Portanto, a HasValuepropriedade de uma Nullable<T>instância padrão é false; que por sua vez faz com que a Nullable<T>instância em si agir como null.
Jon Schneider
fonte
Quando altero uma declaração de int? x = null;para int? x;, recebo erros do compilador mais adiante no código: "Uso de variável local não atribuída x".
John Pick
1
@JohnPick Esse é um recurso do compilador C # destinado a evitar bugs que possam surgir por você "esquecer" de inicializar uma variável antes de usá-la. Uma situação em que você pode encontrar um int não inicializado? é quando é uma variável de membro da classe. Exemplos de ambos aqui: blogs.msdn.microsoft.com/abhinaba/2005/11/08/…
Jon Schneider
Então, basicamente, este lugar é seu blog de tecnologia? Você faz perguntas para as quais só precisa executar o código para obter a resposta e, em seguida, responde você mesmo à pergunta no mesmo minuto.
GôTô
4
@JonSchneider justo, meu mal então
GôTô
Compilador dica / aviso do VS é enganosa: Field 'id' is never assigned to, and will always have its default value 0. Estranho, não é?
Hendy Irawan
30

Achei importante compartilhar o Nullable<T>.GetValueOrDefault()método que é particularmente útil ao trabalhar com cálculos matemáticos que usam valores Nullable<int>aka int?. Muitas vezes você não precisa verificar a HasValuepropriedade e pode apenas usar GetValueOrDefault().

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

Linha de comando mostrando o código acima funcionando

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