Zastosuj następującą metodę ogólną:
public static T Get<T>(T value)
{
return value;
}
Jeśli nazywamy to tak Get<string>(s)
, zwrot nie jest zerowalny, a jeśli tak Get<string?>(s)
, to jest zerowalny.
Jednak jeśli wywołujesz go za pomocą ogólnego argumentu, takiego jak Get<T>(x)
i T
nie został rozwiązany, na przykład jest to ogólny argument dla ogólnej klasy, taki jak poniżej ...
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// is result nullable or non-nullable? It depends on T
}
}
W tym przypadku kompilator nie wie, czy ostatecznie zostanie wywołany z typem zerowalnym lub zerowalnym.
Istnieje nowy typ ograniczenia, którego możemy użyć do zasygnalizowania, że T
nie może być zerowy:
public static T Get<T>(T value) where T: notnull
{
return value;
}
Jednak tam, gdzie T
jest nieograniczone i wciąż otwarte, nullability jest nieznany.
Jeśli te niewiadome zostały potraktowane jako zerowalne, możesz napisać następujący kod:
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;
}
}
W przypadku, gdy T
nie było zerowalne, powinniśmy otrzymać ostrzeżenie. Tak więc w przypadku nieznanych typów zerowania chcemy ostrzeżeń podczas dereferencji, ale także ostrzeżeń o potencjalnym przypisaniu null
.