En C # 8, uno debe marcar explícitamente los tipos de referencia como anulables.
Por defecto, esos tipos no pueden contener nulos, algo similares a los tipos de valor. Si bien esto no cambia la forma en que funcionan las cosas debajo del capó, el verificador de tipo requerirá que lo haga manualmente.
El código dado se refactoriza para funcionar con C # 8, pero no se beneficia de esta nueva característica.
public static Delegate? Combine(params Delegate?[]? delegates)
{
// ...[]? delegates - is not null-safe, so check for null and emptiness
if (delegates == null || delegates.Length == 0)
return null;
// Delegate? d - is not null-safe too
Delegate? d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
d = Combine(d, delegates[i]);
return d;
}
Aquí hay un ejemplo de un código actualizado (que no funciona, solo una idea) que aprovecha esta característica. Nos salvó de una verificación nula y simplificó un poco este método.
public static Delegate? Combine(params Delegate[] delegates)
{
// `...[] delegates` - is null-safe, so just check if array is empty
if (delegates.Length == 0) return null;
// `d` - is null-safe too, since we know for sure `delegates` is both not null and not empty
Delegate d = delegates[0];
for (int i = 1; i < delegates.Length; i++)
// then here is a problem if `Combine` returns nullable
// probably, we can add some null-checks here OR mark `d` as nullable
d = Combine(d, delegates[i]);
return d;
}