Как пометить возвращаемое значение по умолчанию в 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
    }
}
Другие вопросы по тегам