空合并运算符的正确关联如何表现?

空合并运算符是正确的关联,这意味着表单的形式

第一?? 第二??第三

被评估为

第一?? (第二??第三)

基于上述规则,我认为以下翻译是不正确的。

从:

Address contact = user.ContactAddress;
if (contact == null)
{
    contact = order.ShippingAddress;
    if (contact == null)
    {
        contact = user.BillingAddress;
    }
}

至:

Address contact = user.ContactAddress ??
                  order.ShippingAddress ??
                  user.BillingAddress;

相反,我认为以下是正确的(如果我错了,请纠正我)

Address contact = (user.ContactAddress ?? order.ShippingAddress) ??
                   user.BillingAddress;

这个规范实际上是自相矛盾的。

C#4规范的第7.13节指出:

空合并运算符是右关联的,这意味着操作从右到左进行分组。 例如,一个表达式的形式a ?? b ?? c a ?? b ?? c a ?? b ?? c被评估为a ?? (b ?? c) a ?? (b ?? c)

另一方面,正如已经指出的那样,7.3.1声称:

除赋值运算符外,所有二元运算符都是左关联的

我完全同意,对于简单的情况,无论你如何进行分组都无关紧要......但如果操作数具有不同的类型,则可能会出现这种情况,因为隐式类型转换会执行有趣的事情。

我会更深入地考虑它,请ping Mads和Eric,并为深入讨论C#的相关部分添加一个勘误(这启发了这个问题)。

编辑:好的,我现在有一个例子,它的确很重要......并且空合并运算符肯定是正确联合的,至少在MS C#4编译器中。 码:

using System;

public struct Foo
{
    public static implicit operator Bar(Foo input)
    {
        Console.WriteLine("Foo to Bar");
        return new Bar();
    }

    public static implicit operator Baz(Foo input)
    {
        Console.WriteLine("Foo to Baz");
        return new Baz();
    }
}

public struct Bar
{
    public static implicit operator Baz(Bar input)
    {
        Console.WriteLine("Bar to Baz");
        return new Baz();
    }
}

public struct Baz
{
}


class Test
{
    static void Main()
    {
        Foo? x = new Foo();
        Bar? y = new Bar();
        Baz? z = new Baz();

        Console.WriteLine("Unbracketed:");
        Baz? a = x ?? y ?? z;
        Console.WriteLine("Grouped to the left:");
        Baz? b = (x ?? y) ?? z;
        Console.WriteLine("Grouped to the right:");
        Baz? c = x ?? (y ?? z);
    }
}

输出:

Unbracketed:
Foo to Baz
Grouped to the left:
Foo to Bar
Foo to Bar
Bar to Baz
Grouped to the right:
Foo to Baz

换一种说法,

x ?? y ?? z

表现相同

x ?? (y ?? z)

但不一样

(x ?? y) ?? z

目前我还不确定为什么在使用(x ?? y) ?? z时从Foo到Bar有两次转换(x ?? y) ?? z (x ?? y) ?? z - 我需要更仔细地检查一下......

编辑:我现在有另一个问题来涵盖双重转换...


Jon的回答是正确的。

只是要清楚: ?? C#中的运算符是正确的关联。 我刚刚通过二元运算符分析器,并验证分析器处理?? 作为右联合。

正如乔恩指出,规范说两者的?? 运算符是右关联的,并且除赋值外的所有二元运算符都是左关联的。 由于规范自相矛盾,显然只有其中之一是正确的。 我会修改spec来表达这样的内容:

除简单赋值,复合赋值和空合并运算符外,所有二元运算符都是左联合的


我看不出它的重要性,两者都是:

(a ?? b) ?? c

a ?? (b ?? c)

有同样的结果!

链接地址: http://www.djcxy.com/p/57955.html

上一篇: How the right associative of null coalescing operator behaves?

下一篇: What is the 'Null coalesce' (??) operator used for?