tags:

views:

588

answers:

5

Hi,

I've just tried the following, the idea being to concatenate the two strings, substituting an empty string for nulls.

string a="Hello";
string b=" World";

-- Debug (amusing that ? is print, doesn't exactly help readability...)

 ? a ?? "" + b ?? ""

-> "Hello"

Correct is:

? (a??"")+(b??"")
"Hello World"

I was kind of expecting "Hello World", or just "World" if a is null. Obviously this is todo with operator precedence and can be overcome by brackets, is there anywhere that documents the order of precedence for this new operator.

(Realising that I should probably be using stringbuilder or String.Concat)

Thanks.

+3  A: 

The operator precedence is documented on MSDN.

However the precedence on MSDN contradicts the precedence in both the downloadbale C# spec also from microsfot, and the spec on ECMA. Which is a little odd.

Irrespective, as Jon Skeet said in his response, best not to rely on precedence of operators, but to be explicit through use of brackets.

Sam Meldrum
Cheers. Searching for ?? in google was obviously not the way.Quite annoying that it's so low.
AndyM
I think this must be wrong - see ECMA reference, and consider: string a = null; string b = a ?? "foo"; What is b?
Douglas Leeder
That MSDN page is definitely wrong - it contradicts Microsoft's own spec.
Jon Skeet
Leaving answer up as it is the MSDN link which *should* give the right answer. Hopefully Microsoft will fix that. If anyone thinks I should delete, please le me know in comments. Thanks.
Sam Meldrum
I don't think you should delete it, but I suggest you edit the answer to explain that that MSDN page doesn't reflect the contents of the downloadable C# spec.
Jon Skeet
+1  A: 

It interesting that http://msdn.microsoft.com/en-us/library/6a71f45d.aspx and http://en.csharp-online.net/ECMA-334:_14.2.1_Operator_precedence_and_associativity give different precedence to ??.

msdn:

  1. Conditional
  2. Assignment
  3. Null-coalescing
  4. Lambda

ECMA:

  1. Null Coalescing
  2. Conditional
  3. Assignment

I think the msdn must be wrong, consider:

string a = null;
string b = a ?? "foo";
// What is b now?
Douglas Leeder
+6  A: 

Never rely on operator precedence. Always explicitly specify how you want your code to act. Do yourself and others a favour for when you come back to your code.

(a ?? "") + (b ?? "")

This leaves no room for ambiguity. Ambiguity is the breeding ground of bugs.

Garry Shutler
Define "when it matters" - would you use it for a + b * c as well? Even if you regard that as too ambiguous, I suspect there are examples I could find where it matters but *everyone* considers it obvious. I agree with the general idea, but not quite how far you'd go :)
Jon Skeet
I would probably use it in your example as well. I'd much rather it be explicitly set out for me than have to think, even for a second. That second of thought gives opportunity for error.
Garry Shutler
Having realised how extreme I stand on it, I've removed the "when it matters". Though I wouldn't bracket up x + y + z, I feel making the extreme statement makes my point clearer.
Garry Shutler
I'll try to come up with an example which is so obvious that I suspect you wouldn't bracket it :)
Jon Skeet
Hehe. I'm sure you'll think of one but making an extreme stand makes for a better answer in my opinion.
Garry Shutler
Okay, here's a sort of example - do you always bracket for associativity as well as precedence? One of the nice things about ?? is that you can write "a ?? b ?? c ?? d". Given that that's a fairly idiomatic use, I think it's clearer than a ?? (b ?? (c ?? d)). But admittedly that's not precedence :)
Jon Skeet
In that case I would write it as you would. I would however avoid having to write code that did that at all costs! ;)
Garry Shutler
+12  A: 

Aside from what you'd like the precedence to be, what it is according to ECMA, what it is according to the MS spec and what csc actually does, I have one bit of advice:

Don't do this.

I think it's much clearer to write:

string c = (a ?? "") + (b ?? "");

Alternatively, given that null in string concatenation ends up just being an empty string anyway, just write:

string c = a + b;

EDIT: Regarding the documented precedence, in both the C# 3.0 spec (Word document) and ECMA-334, addition binds tighter than ??, which binds tighter than assignment. The MSDN link given in another answer is just wrong and bizarre, IMO. There's a change shown on the page made in July 2008 which moved the conditional operator - but apparently incorrectly!

Jon Skeet
I didn't realize the point about nulls in string concatenation. Nice.
EnocNRoll
It's interesting that: string s= null assigns s to null whereas string s=null+null assigns s to ""
AndyM
for "Don't do this", +1 is not enough.
Simon