En C#, el literal null se utiliza para denotar la ausencia de un valor. Un tipo anulable es un tipo que admite valores null.
Antes de C# 8.0, los tipos de referencia siempre eran anulables y los tipos de valor no. Un tipo de valor se puede convertir en anulable añadiéndole un signo de interrogación (?).
string nullableReferenceType = "hello";
nullableReferenceType = null; // Valid as type is nullable
int nonNullableValueType = 5;
nonNullableValueType = null; // Compile error as type is not nullable
int? nullableValueType = 5; // Define nullable value type
nullableValueType = null; // Valid as type is nullable
Acceder a un miembro de una variable nula no provoca un error de compilación, pero da lugar a que se lance una NullReferenceException en tiempo de ejecución:
string sentence = null;
// Throws NullReferenceException at runtime
sentence.Length;
Para contrarrestar este tipo común de error, C# 8 permite optar por una característica que hace que los tipos de referencia no sean anulables de forma predeterminada:
string nonNullableReferenceType = "book";
nonNullableReferenceType = null; // Compile warning (no error!)
string? nullableReferenceType = "movie";
nullableReferenceType = null; // Valid as type is nullable
Para trabajar de forma segura con valores anulables, comprueba si son null antes de usarlos:
string NormalizedName(string? name)
{
if (name == null)
{
return "UNKNOWN";
}
// Value is not null at this point, so no compile warning
// and no runtime NullReferenceException being thrown
return name.ToUpper();
}
NormalizedName(null); // => "UNKNOWN"
NormalizedName("Elisabeth"); // => "ELISABETH"
El operador ?? permite devolver un valor predeterminado cuando el valor es null:
string? name1 = "John";
name1 ?? "Paul"; // => "John"
string? name2 = null;
name2 ?? "George"; // => "George"
El operador ?. permite llamar a miembros de forma segura en un valor que posiblemente sea null:
string? fruit = "apple";
fruit?.Length; // => 5
string? vegetable = null;
vegetable?.Length; // => null
En este ejercicio vas a escribir código para imprimir etiquetas identificativas con el nombre de los empleados de una fábrica.
Los empleados tienen un ID, un nombre y el nombre de su departamento. Las etiquetas identificativas de los empleados tienen el siguiente formato: "[id] - name - DEPARTMENT". Implementa el método Badge.Print() (static) para devolver la etiqueta identificativa de un empleado:
Badge.Print(734, "Ernest Johnny Payne", "Strategic Communication");
// => "[734] - Ernest Johnny Payne - STRATEGIC COMMUNICATION"
Ten en cuenta que el departamento debe escribirse en mayúsculas en la etiqueta.
Debido a una peculiaridad del sistema informático, a veces los empleados nuevos aún no tienen un ID cuando empiezan a trabajar en la fábrica. Como las etiquetas identificativas son obligatorias, recibirán una etiqueta temporal sin el prefijo del ID. Modifica el método Badge.Print() (static) para admitir a los empleados nuevos que aún no tienen un ID:
Badge.Print(id: null, "Jane Johnson", "Procurement");
// => "Jane Johnson - PROCUREMENT"
Incluso el propietario de la fábrica tiene que llevar una etiqueta identificativa en todo momento. Sin embargo, el propietario no tiene departamento. En este caso, la etiqueta debe imprimir "OWNER" en lugar del nombre del departamento. Modifica el método Badge.Print() (static) para imprimir una etiqueta para el propietario:
Badge.Print(254, "Charlotte Hale", department: null);
// => "[254] - Charlotte Hale - OWNER"
Ten en cuenta que es posible que el propietario sea también un empleado nuevo:
Badge.Print(id: null, "Charlotte Hale", department: null);
// => "Charlotte Hale - OWNER"
Regístrate en Exercism para aprender y dominar C# con 62 conceptos178 ejercicios y mentoría humana real, todo gratis.