Tipos de valor que aceptan valores NULL: Aspectos básicos de C#

Tip

Este artículo forma parte de la sección Aspectos básicos de los desarrolladores que conocen al menos un lenguaje de programación y están aprendiendo C#. Si no está familiarizado con la programación, comience primero con los tutoriales de introducción . Para obtener más información, consulte tipos de valor anulables en la referencia del lenguaje.

Un tipo de valor anulableT? representa todos los valores de su tipo de valor subyacente T, además de un valor adicional null. Una variable de tipo int? contiene cualquier entero o null para representar "sin valor".

Los tipos de valor como int, booly DateTime no pueden contener null de forma predeterminada. Este comportamiento es eficaz y evita muchos errores. Sin embargo, esta limitación crea un problema cuando un valor podría estar ausente realmente. Un escenario común es leer desde una base de datos: una columna de enteros puede contener un número o podría no contener ningún valor (NULL en SQL). Un plano int no puede representar esa ausencia, pero int? sí.

Declarar un tipo de valor anulable

Anexe ? a cualquier tipo de valor para que sea null:

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

El valor predeterminado de un tipo de valor que acepta valores NULL es null, no el valor predeterminado del tipo subyacente.

Comprobar si hay un valor presente

La manera recomendada de comprobar un tipo de valor que acepta valores NULL y extraer su valor es con un patrón de tipo:

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.

El is int degrees patrón coincide solo cuando temperature no es NULL y enlaza simultáneamente el valor a degrees. De este modo, se lleva a cabo tanto la comprobación de valores Null como la extracción del valor en un solo paso.

Como alternativa, use las HasValue propiedades y Value :

int? count = 42;

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

Prefiere el patrón is T value para el nuevo código. Presenta una nueva variable que no acepta valores Null con ámbito de la rama coincidente, lo que hace que la intención sea más clara y elimine cualquier tentación de usar Value accidentalmente fuera de una comprobación Null, donde produciría un InvalidOperationException.

También puede comparar directamente con null:

int? quantity = null;

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

Obtención de un valor con una reserva

Cuando necesite un valor que no acepta Null de uno que acepta Null, use GetValueOrDefault o el operador de uso combinado de null ??:

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

El operador ?? suele ser más limpio en línea:

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

Ambos enfoques devuelven el valor real cuando hay uno presente y la reserva que especifique cuando no lo haya.

Aritmética con tipos de valor anulables

Los operadores de comparación y aritméticos en tipos de valores que aceptan valores Null se levantan: cuando cualquiera de los operandos es null, el resultado es null en lugar de un error.

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

Null se propaga a través de la aritmética de forma predeterminada. Para evitar que un resultado null se produzca en cascada, extraiga el valor con ?? o GetValueOrDefault antes de usarlo en un cálculo.

Consulte también