Как пометить возвращаемое значение по умолчанию в C# 8 как обнуляемое только для классов?
В настоящее время я пытаюсь применить новую функцию необязательного ссылочного типа C# 8.0 к существующему коду и не знаю, как исправить предупреждение CS8603 в следующем методе десериализации данных:
T ReadOptional<T>() where T : IEntity, new()
{
if (ReadBoolean())
{
T instance = new T();
instance.Read(this); // IEntity method
return instance;
}
else
{
// CS8603 Possible null reference return.
return default;
}
}
Как видите, метод может вернуть null
(классы) / default
(структурирует), если предыдущий логический тип был ложным, в противном случае он возвращает T
экземпляр, который может быть что-либо реализации IEntity
,
Однако я не могу пометить тип возвращаемого значения как T?
потому что это на самом деле не вернется null
если T
является структурой, на которую правильно указывает ошибка компилятора CS8627:
// CS8627: A nullable type parameter must be known to be a value type or non-nullable
// reference type. Consider adding a 'class', 'struct', or type constraint.
T? ReadOptional<T>() where T : IEntity, new()
- Я не могу это исправить, убедившись, что
T
имеетclass
ограничение, как я также ожидаюstruct
экземпляры для работы с этим методом (возвращаяdefault
). - Я не могу создать перегрузку с
T
иметьstruct
ограничение, поскольку перегрузки не могут отличаться только ограничениями. - Я мог бы создавать методы с разными именами, но это сломало бы интерфейс библиотеки и слишком много кода зависело от него.
Есть ли какой-либо синтаксис, чтобы исправить необнуляемое предупреждение, не нарушая возможность возврата default
экземпляры для структур?
1 ответ
Просматривая подобный вопрос по C# 8.0 здесь, я заполнил пробел в моих знаниях об обнуляемых ссылочных типах: есть оператор, допускающий ноль!
который может исправить предупреждение для меня прямо здесь:
T ReadOptional<T>() where T : IEntity, new()
{
if (ReadBoolean())
{
T instance = new T();
instance.Read(this); // IEntity method
return instance;
}
else
{
return default!; // <-- note the exclamation mark
}
}