Та же ошибка возникает, если вы не используете ограничение notnull
. Вам нужно указать, что это за тип с ограничением class
или struct
. Вам не нужно указывать notnull
, так как структуры всегда имеют значение NULL, а также с включенными типами ссылок NULL, также как и классы.
Просто добавьте where T:class
или where T:struct
.
Типы ссылок
Если добавить ограничение class
, например:
#nullable enable
interface IDataAdapter<T>
where T:class
{
T? Read (Guid id); // error CS8627
void Something(T input);
}
class StringAdapter:IDataAdapter<string>
{
public string Read(Guid id)=>id.ToString();
public void Something(string input){}
}
Следующий вызов вызовет предупреждение:
var adp=new StringAdapter();
string? x=null;
adp.Something(x); //CS8604: Possible null reference argument ....
Типы значений
Использование struct
для создания IntAdapter
с другой стороны приводит к ошибке компиляции, если аргумент обнуляется:
interface IDataAdapter<T>
where T:struct
{
T? Read (Guid id); // error CS8627
void Something(T input);
}
class IntAdapter:IDataAdapter<int>
{
public int? Read(Guid id)=>id.ToString().Length;
public void Something(int input){}
}
void Main()
{
var adp=new IntAdapter();
int? x=null;
adp.Something(x); //CS1503: Cannot convert from int? to int
}
Это потому, чтосгенерированные методы, которые ожидают int?
вместо int
.
Объяснение
Причина в том, что компилятор должен генерировать очень разные коды в каждомкейс. Для класса это не должно делать ничего особенного. Для структуры необходимо сгенерировать Nullable .
Это объясняется в разделе The issue with T?
в Попробуйте ссылочные типы Nullable :
Это различие между типами значений Nullable и ссылочными типами Nullable встречается в такой схеме:
void M<T>(T? t) where T: notnull
Это будет означать, что параметр является обнуляемой версией T и Tвынужден быть ненулевым. Если бы T была строкой, то фактическая сигнатура M была бы M ([NullableAttribute] T t), но если бы T был int, то M был бы M (Nullable t). Эти две сигнатуры принципиально различны, и эта разница не может быть согласована.
Из-за этой проблемы между конкретными представлениями обнуляемых ссылочных типов и обнуляемых типов значений любое использование T? Вы также должны требовать, чтобы T был либо классом, либо структурой.