Как пометить возвращаемое значение по умолчанию в C # 8 как обнуляемое только для классов? - PullRequest
0 голосов
/ 20 февраля 2019

В настоящее время я пытаюсь применить новую функцию необязательного ссылочного типа 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 Ответ

0 голосов
/ 20 февраля 2019

Просматривая аналогичный вопрос по 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
    }
}
...