Nullables C#

Tipos Nullable (?)

El operador ? se usa para convertir un tipo de valor en un tipo de valor nullable, el cual puede contener un valor nulo.

int? num = null;
if(num is int numValue)
{
	Console.WriteLine(numValue); 
}

Acceso condicional nulo a miembros (?. o ?[])

(!) (revisar abajo como usarlo mejor junto al operador ??) (!)

Este operador permite acceder a un miembro de un objeto solo si el objeto no es nulo, evitando asi una NullReferenceException. Si no se cumple, devuelve null.

  • si a es nulo, el resultado de a?.x o a?[x] es null
  • si a no es nulo, el resultado de a?.x o a?[x] es el mismo que a.x o a[x]
string[] nombres = null;
int? longitud = nombres?.Length; // asigna null en lugar de lanzar una excepcion

Coalescencia de Nulos (??)

Se usa para proporcionar un valor por defecto en caso de que una expresion nullable contenga un null.

sin este operador

// DON'T DO THIS
string name = GetName();
if(name == null)
{
	name = "unknown";
}

se reemplaza por esto usando el operador

// do this instead
string name = GetName() ?? "unknown";

Se recomienda usar ?? en vez de expresiones ternarias para comprobar un null

// DON'T DO THIS
var v = x == null ? x : y;

// do this instead
var v = x ?? y;

uso de operador .? junto a ??

Se puede usar el operador ?? junto a .? para asignar un valor por defecto, en caso de que alguna propiedad accedida mediante .? sea nula en algún punto

ejemplo 1

string[] nombres = // something 
string nombre = nombres?[index] ?? "NotFound"; // array is null or name not found

ejemplo 2

// if the value someList from request is null, this if will check as false
if ((request?.someList?.Count ?? 0) <= 0)
{
	// ... do something
}

También se puede usar junto a un throw para hacer más concisa la asignación de valores.

public string Name
{
	get => name;
	set => name = value ?? throw new ArgumentNullException(nameof(value), "Name cannot be null");
}

Asignacion de coalescencia de nulos (??=)

reemplaza este formato de código

if (variable is null) 
{
	variable = "something";
}

por esto. lo hace más conciso

variable ??= "something";

Reference(s)

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/null-coalescing-operator
https://learn.microsoft.com/en-us/dotnet/fundamentals/code-analysis/style-rules/ide0029-ide0030-ide0270
https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/member-access-operators#null-conditional-operators–and-