简体   繁体   中英

How to test the right-associativity of conditional operator in c#

I wrote the following code.

static void Main(string[] args)
{
    var xyz = 10 < 11 ? 12 : 5 < 21 ? getValue() : 15;
    Console.WriteLine(xyz);
    Console.ReadLine();
}

static int getValue()
{
    Console.WriteLine("hello");
    return 100;
}

Since the first condition is always true, the value that xyz will get is 12 but since the conditional operator is itself right associative, I was expecting that the getValue() function would be executed first and "hello" would be printed. When I run this code, it doesn't run that way.

Can someone please enlighten me on this behavior.

This:

var xyz = 10 < 11 ? 12 : 5 < 21 ? getValue() : 15;

is treated as:

var xyz = 10 < 11 ? 12 : (5 < 21 ? getValue() : 15);

So we have a conditional expression with:

  • Condition: 10 < 11
  • First branch: 12
  • Second branch: 5 < 21 ? getValue() : 15 5 < 21 ? getValue() : 15

As 10 < 11 is true, the first branch is evaluated but the second branch is not.

The associativity isn't as easily shown with your code as with code which uses a bool expression for every operand - as that could compile with either associativity.

Consider this code:

using System;

class Test
{
  static void Main()
  {            
    var xyz = Log(1, true) ? Log(2, true) : Log(3, true) ? Log(4, false) : Log(5, true);
  }

  static bool Log(int x, bool result)
  {
    Console.WriteLine(x);
    return result;
  }
}

Renaming each Log(x, ...) to Lx for simplicity, we have:

var xyz = L1 ? L2 : L3 ? L4 : L5;

That could be handled as:

// Right associativity
var xyz = L1 ? L2 : (L3 ? L4 : L5);

// Left associativity
var xyz = (L1 ? L2 : L3) ? L4 : L5;

Given the results we're returning, with right-associativity we'd expect to see output of 1, 2. With left-associativity, we'd see 1, 2, 4. The actual output is 1, 2, showing right-associativity.

If you translate the code into in..else statement, it would be -

        int xyz = 0;
        if (10 < 11)
        {
            xyz = 12;
        }
        else
        {
            if (5 < 21)
            {
                xyz = getValue();
            }
            else
            {
                xyz = 15;
            }
        }

And since the first if condition evaluates to true, the else will not execute and you will get 12 printed on console.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM