Tipos de valor nulo: Fundamentos de C#

Sugestão

Este artigo faz parte da secção de Fundamentos para programadores que conhecem pelo menos uma linguagem de programação e estão a aprender C#. Se és novo na programação, começa primeiro pelos tutoriais para começar . Para mais detalhes, consulte Tipos de valor nulo na referência da linguagem.

Um tipo T? representa todos os valores do seu tipo Tsubjacente , mais um valor adicionalnull. Uma variável do tipo int? contém qualquer inteiro ou null para representar "nenhum valor".

Tipos de valor como int, bool e DateTime não conseguem conter null por defeito. Este comportamento é eficiente e previne muitos erros. No entanto, esta limitação cria um problema quando um valor pode realmente estar ausente. Um cenário comum é ler a partir de uma base de dados: uma coluna inteira pode conter um número, ou pode não conter qualquer valor (NULL em SQL). Um simples int não pode representar essa ausência, mas int? pode.

Declarar um tipo de valor nulo

Adicione ? a qualquer tipo de valor para o tornar anulável:

int?    age      = null;    // integer with no value yet
double? price    = 9.99;    // nullable double with a value
bool?   isActive = null;    // boolean with no value

age = 30;                   // assign a value later

int?[] scores = [100, null, 85, null, 72]; // array with absent entries

O valor padrão de um tipo de valor anulável é null, não o valor padrão do tipo subjacente.

Verifique se existe um valor presente

A forma recomendada de verificar um tipo de valor nullável e extrair o seu valor é com um padrão de tipos:

int? temperature = 72;

if (temperature is int degrees)
{
    Console.WriteLine($"Temperature is {degrees}°F.");
}
else
{
    Console.WriteLine("Temperature is not recorded.");
}
// Output: Temperature is 72°F.

O is int degrees padrão corresponde apenas quando temperature não é nulo, e simultaneamente liga o valor a degrees. Obtém tanto a verificação de nulo como a extração de valor numa só etapa.

Alternativamente, use as propriedades HasValue e Value

int? count = 42;

if (count.HasValue)
{
    Console.WriteLine($"Count is {count.Value}.");
}
else
{
    Console.WriteLine("Count has no value.");
}
// Output: Count is 42.

Prefiro o is T value padrão para código novo. Introduz uma nova variável não anulável com âmbito associado ao ramo correspondente, o que torna a intenção mais clara e elimina qualquer tentação de usar Value acidentalmente fora de uma verificação de nulo, pois lançaria um InvalidOperationException.

Também pode comparar diretamente com null:

int? quantity = null;

if (quantity != null)
{
    Console.WriteLine($"Quantity: {quantity.Value}");
}
else
{
    Console.WriteLine("Quantity is not set.");
}
// Output: Quantity is not set.

Obtenha um valor com um valor de substituição

Quando precisar de um valor não nulo a partir de um anulável, use GetValueOrDefault ou o operador de coalescimento nulo ??:

int? rating = null;

int result1 = rating.GetValueOrDefault();    // 0 (default for int)
int result2 = rating.GetValueOrDefault(-1);  // -1 (specified fallback)

Console.WriteLine(result1); // 0
Console.WriteLine(result2); // -1

rating = 5;
int result3 = rating.GetValueOrDefault(-1);  // 5 (actual value)
Console.WriteLine(result3); // 5

Costuma ser mais limpo usar o operador ?? em linha.

int? priority = null;

int effective = priority ?? 0;  // 0 because priority is null
Console.WriteLine(effective);   // 0

priority  = 3;
effective = priority ?? 0;      // 3 because priority has a value
Console.WriteLine(effective);   // 3

Ambas as abordagens devolvem o valor real quando uma está presente, e o plano B que especificas quando não está.

Aritmética com tipos de valor anuláveis

Operadores aritméticos e de comparação sobre tipos de valor nulo são removidos: quando qualquer um dos operandos é null, o resultado é null em vez de um erro.

int? a = 10;
int? b = 20;
int? c = null;

int? sum     = a + b;   // both non-null: result is 30
int? product = a * c;   // one operand is null: result is null

Console.WriteLine(sum);               // 30
Console.WriteLine(product.HasValue);  // False — null propagates through arithmetic

Nulo propaga-se através da aritmética por padrão. Para evitar que um resultado nulo se espalhe ainda mais, extraia o valor com ?? ou GetValueOrDefault antes de o usar num cálculo.

Ver também