Візьміть такий загальний метод:
public static T Get<T>(T value)
{
return value;
}
Якщо ми називаємо це так Get<string>(s) , повернення не є нульовим, а якщо ми це робимо Get<string?>(s), воно є незмінним.
Однак якщо ви називаєте це загальним аргументом, як Get<T>(x)іT називаєте не вирішено, наприклад, це загальний аргумент для вашого загального класу, як нижче ...
class MyClass<T>
{
void Method(T x)
{
var result = Get<T>(x);
// is result nullable or non-nullable? It depends on T
}
}
Тут компілятор не знає, чи зрештою він буде викликаний з нульовим чи ненульовим типом.
Є нове обмеження типу, яке ми можемо використовувати для сигналізації, яке Tне може бути нульовим:
public static T Get<T>(T value) where T: notnull
{
return value;
}
Однак де T не обмежено і все ще відкрито, зведена нанівець невідомо.
Якщо ці невідомі трактувались як нульові, тоді можна написати наступний код:
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;
}
}
У випадку, коли це Tбуло нерегульованим, нам слід було б отримати попередження. Тож із невідомими типами зведеності ми хочемо попередження при перенаправлення, а також попередження про присвоєння потенційно null.