三元操作员既左手术又右手手术......或两者兼而有之

时间:2015-11-26 12:43:20

标签: c# ternary-operator order-of-execution

问题是:如果您明白此问题,请向我解释我没看到的内容。我的问题是:三元如何实际运作?澄清我的问题:左右相关性在这里意味着什么?为什么关联性与评估顺序不一样?这显然就像是if else声明。它不是从右到左评估的。在我看来,从左到右是联想的。

我让布尔人试图证明这一点。它告诉我它不是正确的联想。(我可能不明白正确的联想意味着什么。)如果它是正确的联想,它会像这样工作,这是给我的答案:

“由于此运算符是右关联的,因此您的代码可以作为;”

true ? false ? false ? false ? 3 : 4 : 5 : 6 : 7
evaluated as;

true ? false ? false ? (false ? 3 : 4) : 5 : 6 : 7
which evaluated as;

true ? false ? false ? 4 : 5 : 6 : 7
which evaluated as;

true ? false ? (false ? 4 : 5) : 6 : 7
which evaluated as;

true ? false ? 5 : 6 : 7
which evaluated as;

true ? (false ? 5 : 6) : 7
which evaluated as;

true ? 6 : 7
which returns 6.

我试图证明这一点,就像这样:

    int Proof = ternaryTrueOne() ? ternaryTrueTwo() ? ternaryFalseOne() ? 
ternaryTrueThree() ? ternaryFalseTwo() ? 2 : 3 : 4 : 5 : 6 : 7;
        static bool ternaryTrueOne()
    {
        Console.WriteLine("This is ternaryTrueOne");
        return true;
    }
    static bool ternaryTrueTwo()
    {
        Console.WriteLine("This is ternaryTrueTwo");
        return true;
    }
    static bool ternaryTrueThree()
    {
        Console.WriteLine("This is ternaryTrueThree");
        return true;
    }
    static bool ternaryFalseOne()
    {
        Console.WriteLine("This is ternaryFalse");
        return false;
    }
    static bool ternaryFalseTwo()
    {
        Console.WriteLine("This is ternaryFalseTwo");
        return false;
    }

在这种情况下,将以相同的方式评估。对?这意味着ternaryfalsetwo会首先写入控制台。但它没有。它完全没有写。它实际上是这样的,并且我已经将三元表达式写为if语句。它从左到右工作,并且不必评估其余的代码。在第一个错误陈述之后,所有其他陈述都无法达到。

private static int Proof2()
{
    if (ternaryTrueOne())
    {
        if (ternaryTrueTwo())
        {
            if (ternaryFalseOne())
            {
                if (ternaryTrueThree())
                {
                    if (ternaryFalseTwo())
                    {
                        return 6;
                    }
                    else
                    {
                        return 7;
                    }
                    return 5;
                }
                else
                {
                    return 6;
                }
                return 4;
            }
            else
            {
                return 5;
            }
            return 3;
        }
        else
        {
            return 4;
        }
        return 2;
    }
    else
    {
        return 3;
    }
}

原来的回答是错的吗?正确的关联性究竟意味着什么?

2 个答案:

答案 0 :(得分:5)

由于三元条件运算符在运算符优先级表中有自己的位置(即没有其他运算符具有与其完全相同的优先级),因此关联性规则仅在消除条件运算符与其他运算符的歧义时适用。

从右到左的关联性意味着隐含的括号围绕最右边的三元组。

即,

a ? b : c ? d : e

相当于

a ? b : (c ? d : e)

https://en.wikipedia.org/wiki/Operator_associativity是一个很有用的链接。

答案 1 :(得分:4)

相关性和执行顺序是相关的,但不相同。

无论执行是什么都存在相关性 - 它在数学中定义,它完全由纯函数组成,因此"执行顺序"与结果无关。

C#中三元运算符的执行顺序非常简单:

  1. 评估条件
  2. 如果条件为真,则评估trueBranch;如果条件为假,则评估falseBranch
  3. 您可以将关联性规则想象为" parens属于哪个"。

    考虑一下:

    a ? b : c ? d : e
    

    如果我们对关联性的工作方式一无所知,我们可以看到不同的方法:

    • (a?b:c)? d:e
    • a? b:(c?d:e)

    第一种方法是左联想,第二种方法是右联想

    不应该很难看出这两种方法会导致不同的结果。例如,

    (true ? true : false) ? false : false // false
    true ? true : (false ? false : false) // true
    

    现在,如果你在单独的if语句中重写它(通常 isn' t 实际执行三元组的方式,但它会这样做),你就是'得到这个:

    if (a)
    {
      return b;
    }
    else
    {
      if (c) return d;
      else return e;
    }
    

    评估与简单的三元评估相同:

    1. 评估条件a
    2. 如果为true,请评估并返回b;否则继续
    3. 评估条件c
    4. 如果为true,请评估并返回d;否则评估并返回e
    5. 这应该明确关联性和执行顺序是如何工作的。所以我们可以完成这次旅行,并解释你的示例。

      我们有一系列嵌套条件:

      a ? b ? c ? 0 : 1 : 2 : 3
      

      关联性如何适用于此?它没有。这里没有关联操作!你正在做的是:

      a ? (b ? (c ? 0 : 1) : 2) : 3
      

      没有其他方法可以放置parens - 这是解析运算符的唯一可行方法。

      由于三元运算符是三元运算符,因此有点难以看到,但当您将其重写为函数(例如"非内联运算符")时,它变得更加明显:

      var f = (a, b, c) => a ? b : c;
      f(a, f(b, f(c, 0, 1), 2), 3);
      

      没有含糊之处 - 没有其他方法可以解析这个表达式。

      显示与二元运算符的关联性稍微简单一些,因此请考虑以下情况:

      a - b - c
      

      如果你不了解-的关联性,你可以看到两种替代方法 - (a - b) - ca - (b - c),这可以给你两个不同的结果。因此,- 关联。

      +比较,这是("完全")关联 - (a + b) + ca + (b + c)完全相同。