Логическое ИЛИ и порядок вычисления троичного оператора - PullRequest
0 голосов
/ 09 апреля 2020

Здесь операторы с самым высоким приоритетом появляются вверху таблицы, а операторы с самым низким приоритетом - внизу. Внутри выражения операторы с более высоким приоритетом вычисляются первыми.

Логическое ИЛИ || Слева направо

Условно?: Справа налево

Пример:

if ( true || false ? false : true )
{
     Console.WriteLine(String.Format("WHY?"));
}

Как я вижу это должно быть: true || (false ? false : true)

Как мне кажется, это работает в моем случае: (true || false) ? false : true

Почему условие никогда не будет выполнено, если условное ИЛИ имеет более высокий приоритет по сравнению с троичный оператор?

UPD1: Смотри, первое и третье условия помечены как недоступные

UPD2: логическое ИЛИ не должно даже проверить условия, следующие за ним, если он уже нашел один истинный

1 Ответ

1 голос
/ 09 апреля 2020

Приоритет оператора - все о разрешении неясностей. Скажем, например, у нас есть два оператора op1 и op2 и следующее выражение:

x = a op1 b op2 c

Мы могли бы решить это логически как

tmp = a op1 b
x = tmp op2 c

Но это также было бы возможно сначала оценить op2, вот так:

tmp = b op2 c
x = a op1 tmp

Это неоднозначно. Чтобы решить эту двусмысленность, мы могли бы потребовать скобки или дать одному из операторов более высокий приоритет. Это в основном то же самое, что мы используем в математике с выражением типа 1 + 2 * 3, где умножение имеет более высокий приоритет и должно вычисляться первым.

Ват, что это значит для вашего примера? Как вы уже написали, || имеет более высокий приоритет, чем ?:. Это означает, что

true || false

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

true ? false : true

и всегда будет false.

Как компилятор примет это решение? Давайте (упрощенно) посмотрим на шаги:

  1. изначально компилятор видит true, что уже является значением.
  2. компилятор видит || и теперь знает, что там должен следовать за другим значением или оцененным выражением.
  3. тогда компилятор видит false. Это может быть значением, но, поскольку оно может быть частью другого выражения, оно еще не сделано.
  4. Затем компилятор встречает ?, который он идентифицирует как троичный оператор
  5. , поскольку троичный имеет более низкий приоритет, чем ||, он должен рассматривать все выражение true || false как первый операнд троичного числа.

Что касается того, почему троичный оператор имеет более низкий приоритет, чем || I Можно только предположить, что это для согласованности. Тернар является не только единственным оператором с тремя операндами, но также только второй и третий должны иметь один и тот же тип данных, тогда как первый всегда равен bool. Более низкий приоритет гарантирует, что эти два назначения семантически одинаковы:

bool b = condition1 || condition2 ? true : false;
int i = condition1 || condition2 ? 23 : 42;
...