Publicaciones
C# 8 - Tipos de referencia anulables
4 de noviembre de 2019 • 4 min de lectura
Microsoft está agregando una nueva característica a C# 8 llamada Tipos de referencia anulables. Lo cual, al principio, es confuso porque todos los tipos de referencia son anulables… entonces, ¿cómo es esto diferente? A partir de ahora, si la característica está habilitada, los tipos de referencia no son anulables, a menos que los anote explícitamente como anulables.
Déjame explicar.
Tipos de referencia anulables
Cuando los Tipos de referencia anulables están habilitados y el compilador cree que un tipo de referencia tiene el potencial de ser nulo, te advierte. Verás mensajes de advertencia de Visual Studio:
Y advertencias de compilación:
Para eliminar esta advertencia, agrega un signo de interrogación al final del tipo de referencia. Por ejemplo:
public string StringTest()
{
string? notNull = null;
return notNull;
}
Ahora el tipo de referencia se comporta como lo hacía antes de C# 8.
Esta característica se habilita agregando <span class="inline-code"> #nullable enable </span> en la parte superior de cualquier archivo C# o agregando <span class="inline-code">lt;NullableReferenceTypes>true</NullableReferenceTypes></span> al archivo .csproj. De forma predeterminada, no está habilitada, lo cual es bueno porque si estuviera habilitada, cualquier base de código existente probablemente se iluminaría como un árbol de Navidad.
El debate sobre nulos
¿Por qué Microsoft está agregando esta característica ahora? Los nulos han sido parte del lenguaje desde, bueno, el principio. Honestamente, no sé por qué. Siempre he usado nulos, es un hecho de la vida en C#. No me di cuenta de que no tener nulos era una opción… Quizás la vida sea mejor sin ellos. Lo descubriremos.
¿Deberías o no deberías usar nulos? He resumido el debate continuo tal como lo entiendo.
A favor
El argumento a favor de los nulos es generalmente que un objeto tiene un estado desconocido. Este estado desconocido se representa con nulo. Lo ves con el tipo de dato bit en SQL Server, que tiene 3 valores, nulo (no establecido), 0 y 1. También lo ves en las interfaces de usuario, donde a veces es importante saber si un usuario tocó un campo o no. Alguien podría contrarrestar diciendo: “En lugar de nulo, ¿por qué no crear un tipo de estado desconocido o un estado ‘no establecido’?” ¿Cómo es esto diferente de nulo? Aún tendrías que verificar este estado adicional. Ahora estás creando estados desconocidos para cada instancia. ¿Por qué no simplemente usar nulo y tener un estado desconocido global?
En contra
El argumento en contra de los nulos es que es un tipo de dato diferente y debe verificarse cada vez que uses un tipo de referencia. El resultado neto es código como este:
var user = GetUser(username, password);
if(user != null)
{
DoSomethingWithUser(user);
} else
{
SetUserNotFoundErrorMessage()
}
Si el método GetUser devolviera un usuario en todos los casos, incluso cuando el usuario no se encuentra. Si el código nunca devuelve nulo, entonces es una pérdida protegerse contra ello e idealmente, esto simplifica el código. Sin embargo, en algún momento, tendrás que verificar un usuario vacío y mostrar un mensaje de error. No usar un nulo no elimina la necesidad de cumplir con el caso de negocio de un usuario no encontrado.
¿Es esta característica una buena idea?
El propósito de esta característica NO es eliminar el uso de nulos, sino hacer la pregunta: “¿Hay una mejor manera?” Y a veces la respuesta es “No”. Si podemos eliminar la verificación constante de nulos con un poco de previsión, lo que a su vez simplifica nuestro código. Estoy dentro. La buena noticia es que C# ha hecho que trabajar con nulos sea trivial.
Temo que algunos adopten una postura dogmática e insistan en eliminar los nulos en detrimento de un sistema. Esto es una tarea de tontos, porque los nulos son integrales a C#.
¿Es Tipos de referencia anulables una buena idea? Lo es, si el resultado final es código más simple y menos propenso a errores.
Autor: Chuck Conway es un Ingeniero de IA con casi 30 años de experiencia en ingeniería de software. Construye sistemas de IA prácticos—canalizaciones de contenido, agentes de infraestructura y herramientas que resuelven problemas reales—y comparte lo que está aprendiendo en el camino. Conéctate con él en redes sociales: X (@chuckconway) o visítalo en YouTube y en SubStack.