Что такое Неизвестный Nullability в C # 8?

12

В C # 8.0 мы можем иметь обнуляемые ссылочные типы. Документы утверждают, что существует 4 типа обнуляемости. Первые 3 довольно понятны, но я не понимаю смысла «неизвестного». В документах говорится, что он используется с обобщениями, но когда я пытаюсь вызвать метод для неограниченной переменной типа T в обобщениях, он просто предупреждает, что тип обнуляемый. Я не вижу разницы между неизвестным и обнуляемым. Почему существует неизвестное? Как это проявляется?

Stilgar
источник

Ответы:

12

Возьмите следующий общий метод:

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
    }
}

Здесь компилятор не знает, будет ли он в конечном итоге вызываться с типом NULL или NULL.

Существует новое ограничение типа, которое мы можем использовать для сигнализации, который 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.

Стюарт
источник
Когда я делаю var result = Test.Get <T> (x); result.ToString (); компилятор жалуется на разыменование возможно нулевого значения. Я не вижу, как в этом случае unknown отличается от просто nullable.
Стилгар
1
С точки зрения предупреждений они ведут себя одинаково, но они семантически различны. Вы могли бы сказать, что разница академическая, и если это была ваша точка зрения, то я согласен.
Стюарт
1
Я все еще хотел бы знать, почему была введена разница. Кажется странным вводить такое различие в языке для академических целей.
Стилгар
Мой плохой, просто перечитал спецификацию, обновил ответ, последняя часть объясняет это.
Стюарт
1
Ах, это больше похоже на это
Стилгар