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 T
nã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 T
nã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 T
nã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
.