Візьміть такий загальний метод:
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
.