Prenez la méthode générique suivante:
public static T Get<T>(T value)
{
return value;
}
Si nous l'appelons comme Get<string>(s)
, le retour n'est pas nul, et si nous le faisons Get<string?>(s)
, il est nul.
Cependant, si vous l'appelez avec un argument générique comme Get<T>(x)
et T
n'est pas résolu, par exemple, c'est un argument générique pour votre classe générique comme ci-dessous ...
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// is result nullable or non-nullable? It depends on T
}
}
Ici, le compilateur ne sait pas si finalement il sera appelé avec un type nullable ou non nullable.
Il existe une nouvelle contrainte de type que nous pouvons utiliser pour signaler qui T
ne peut pas être nulle:
public static T Get<T>(T value) where T: notnull
{
return value;
}
Cependant, là où il T
n'est pas contraint et toujours ouvert, la nullité est inconnue.
Si ces inconnues ont été traitées comme nullables, vous pouvez écrire le code suivant:
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// reassign result to null, cause we we could if unknown was treated as nullable
result = null;
}
}
Dans le cas où T
n'était pas annulable, nous aurions dû recevoir un avertissement. Donc, avec des types de nullité inconnus, nous voulons des avertissements lors du déréférencement, mais aussi des avertissements pour une affectation potentielle null
.