Ответ 1
На самом деле у вас есть
string text = null;
int? index = text?.IndexOf("Foo", StringComparison.CurrentCultureIgnoreCase);
bool contains = index >= 0;
и int? >= int
является совершенно законным.
Причина, по которой она была разделена, документация для оператора гласит: "Если одна операция в цепочке условного доступа к члену и операция индекса возвращает значение null, то остальные остановки цепочки. Другие операции с более низким приоритетом в выражении продолжаются". Это означает, что .?
будет оценивать вещи с одинаковым приоритетом или выше, прежде чем "создаст значение".
Если вы посмотрите порядок приоритета оператора, вы увидите, что "Операторы реляционного и типового тестирования" в списке значительно ниже, поэтому значение будет создано до применения >=
.
ОБНОВЛЕНИЕ:. Поскольку он был поднят в комментариях, вот раздел спецификации С# 5 о том, как ведут себя теги >=
и другие операторы при работе с нулевым значением. Я не смог найти документ для С# 6.
7.3.7 Поднятые операторы
Поднятые операторы разрешают предопределенные и определяемые пользователем операторы, которые работают с типами значений, не подлежащими нулевому значению, также могут использоваться с нулевыми значениями форм этих типов. Поднятые операторы построены из предопределенных и определяемые пользователем операторы, которые отвечают определенным требованиям, так как описанных ниже:
Для унарных операторов
+ ++ - -- ! ~
существует снятая форма оператора, если типы операндов и результатов являются неинифицируемыми типами значений. Поднятая форма построенный путем добавления сингла? модификатор в операнд и результат типы. Выбранный оператор создает нулевое значение, если операнд ноль. В противном случае снятый оператор разворачивает операнд, применяет основного оператора и обертывает результат.
Для двоичных операторов
+ - * / % & | ^ << >>
существует снятая форма оператора, если операнд и типы результатов все типы значений, не подлежащие обнулению. Поднятая форма построена по добавив сингл? модификатора для каждого операнда и типа результата. Поднятые оператор генерирует нулевое значение, если один или оба операнда равны нулю ( исключение - это и и | операторы bool? типа, как описано в §7.11.3). В противном случае снятый оператор разворачивает операнды, применяет базовый оператор и обертывает результат.
Для операторов равенства
== !=
существует поднятая форма оператора, если типы операндов оба типы с нулевым значением и если тип результата равен bool. Поднятые форма строится путем добавления сингла? модификатора для каждого операнда тип. Поднятый оператор считает два нулевых значения равными, а нулевой значение не равно любому ненулевому значению. Если оба операнда не равны нулю, снятый оператор разворачивает операнды и применяет основные оператора для получения результата bool.
Для реляционных операторов
< > <= >=
существует допустимая форма оператора, если типы операндов являются неинифицируемыми типами значений, и если тип результата равен bool. Поднятые форма строится путем добавления сингла? модификатора для каждого операнда тип. Поднятый оператор выдает значение false, если один или оба операнды равны нулю. В противном случае снятый оператор разворачивает операнды и применяет основной оператор для получения результата bool.