null coalescing operator is right associative, which means an expression of the form
first ?? second ??third
is evaluated as
first ?? (second ?? third)
Based on the above rule, I think the following translation is not correct.
From:
Address contact = user.ContactAddress;
if (contact == null)
{
contact = order.ShippingAddress;
if (contact == null)
{
contact = user.BillingAddress;
}
}
To:
Address contact = user.ContactAddress ??
order.ShippingAddress ??
user.BillingAddress;
Instead, I think the following is right one (Please correct me if I am wrong)
Address contact = (user.ContactAddress ?? order.ShippingAddress) ??
user.BillingAddress;
The spec is actually self-contradictory on this one.
Section 7.13 of the C# 4 spec states:
On the other hand, as has been pointed out, 7.3.1 claims that:
I entirely agree that for simple cases it doesn’t matter how you do the grouping… but there may be cases where it really matters due to implicit type conversions doing interesting things if the operands have different types.
I’ll consider it further, ping Mads and Eric, and add an erratum for the relevant section of C# in Depth (which inspired this question).
EDIT: Okay, I’ve now got an example where it does matter… and the null coalescing operator is definitely right-associative, at least in the MS C# 4 compiler. Code:
Output:
In other words,
behaves the same as
but not the same as
I’m not currently sure why there are two conversions from Foo to Bar when using
(x ?? y) ?? z– I need to check that out more carefully…EDIT: I now have another question to cover the double conversion…