Точная семантика прощающего оператора в C # 8.0? - PullRequest
1 голос
/ 10 ноября 2019

Согласно документации :

Постфикс! Оператор не имеет никакого эффекта времени выполнения - он оценивает результат базового выражения. Его единственная роль состоит в том, чтобы изменить нулевое состояние выражения и ограничить количество предупреждений о его использовании.

Пример:

IEnumerable<object?>? foo = GetFromSomewhere();
IEnumerable<object> bar = foo; // warning CS8619: Nullability of reference types in value of type 'IEnumerable<object?>' doesn't match target type 'IEnumerable<object>'.

(Обратите внимание, что предупреждение неправильно определить тип значения как IEnumerable<object?>?, но утверждает, что это IEnumerable<object?>.)

При добавлении !:

IEnumerable<object?>? foo = GetFromSomewhere();
IEnumerable<object> bar = foo!; // No warning.

!, кажется, изменитьобнуляемость конкретного универсального аргумента (от object? до object) тоже, не только нулевое состояние фактического экземпляра объекта, обозначенное выражением foo.

, но только если я аннотируютип bar явно. Когда вместо этого используется var, поведение больше похоже на то, как я интерпретирую документацию:

IEnumerable<object?>? foo = GetFromSomewhere();
var bar = foo!;
IEnumerable<object> baz = bar; // warning CS8619: Nullability of reference types in value of type 'IEnumerable<object?>' doesn't match target type 'IEnumerable<object>'.

Итак, bar выводится как IEnumerable<object?>, удаляя только самый внешний вопросительный знак.

Какова точная семантика нуль-прощающего оператора C # 8.0 (!)?

1 Ответ

1 голос
/ 11 ноября 2019

Как вы цитировали:

Постфикс! Оператор не имеет никакого эффекта времени выполнения - он оценивает результат базового выражения. Его единственная роль состоит в том, чтобы изменить нулевое состояние выражения и ограничить количество предупреждений о его использовании .

Таким образом, оператор будет ограничивать предупреждения об обнуляемости в целом.

!, похоже, также изменяет обнуляемость конкретного универсального аргумента (от объекта? К объекту)

Вы указали тип bar явно как IEnumerable<object>, а также использовал оператор !, который подавлял предупреждения.

...