Согласно документации :
Постфикс! Оператор не имеет никакого эффекта времени выполнения - он оценивает результат базового выражения. Его единственная роль состоит в том, чтобы изменить нулевое состояние выражения и ограничить количество предупреждений о его использовании.
Пример:
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 (!
)?