Siga o seguinte método genérico:
public static T Get<T>(T value)
{
return value;
}
Se chamarmos assim Get<string>(s), o retorno não será anulável e, se o fizermos Get<string?>(s), será anulável.
No entanto, se você estiver chamando-o com um argumento genérico como Get<T>(x)e Tnão for resolvido, por exemplo, é um argumento genérico para sua classe genérica como abaixo ...
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// is result nullable or non-nullable? It depends on T
}
}
Aqui, o compilador não sabe se, eventualmente, será chamado com um tipo nulo ou não nulo.
Há uma nova restrição de tipo que podemos usar para sinalizar que Tnão pode ser nulo:
public static T Get<T>(T value) where T: notnull
{
return value;
}
No entanto, onde Té irrestrito e ainda está aberto, a nulidade é desconhecida.
Se essas incógnitas forem tratadas como anuláveis, você poderá escrever o seguinte código:
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;
}
}
No caso em que Tnão foi anulável, deveríamos ter recebido um aviso. Portanto, com tipos de nulidade desconhecidos, queremos avisos ao fazer referência à referência, mas também avisos para atribuição potencial null.