The team is asking for your feedback. If you have a couple of minutes, answer these questions or respond to this thread.
Declaration Expressions
C# 6 is introducing a new feature called declaration expressions. It’s cool because it lets you write this code:
if (int.TryParse(s, out int i)) { … i … }
No more separate variable appearing above the conditional. Less ceremony, less ugliness, yippee!!!!!
The initial implementation expanded the scope of the variable to the next larger scope. This allowed you to do stuff like:
GetCoordinates(out var x, out var y);
… // use x and y;
While that might look useful, I hate it because it obscures the declaration of variables that extend across the entire scope – such as the method. This is called spill out and the team plans to remove it.
For clarity, in the condition if statement above, the integer i is in scope within the statement or block that is effectively the “then” clause of the conditional expression. Most of the enclosing blocks you use: do, for, using have a single place to declare a variable.
Yippeee!
The Issue to Resolve…
The question the team is asking for help resolving involves code like this:
if (int.TryParse(s, out int i)) Console.WriteLine("Got integer {0}", i);
else Console.WriteLine("Got no integer {0}", i);
// Do you expect "i" to be in scope in the "else" clause?
The way C# itself is designed (in the .NET Compiler Platform, Roslyn trees) is an else clause is contained inside theif statement. The above use of the variable i is legal (Q1 below).
The scenario most impacted by this decision is a series of else if statements (Q2 below):
if (int.TryParse(s, out var v)) Console.WriteLine("Got integer {0}", v);
else if (double.TryParse(s, out var v)) Console.WriteLine("Got double {0}", v);
else Console.WriteLine("Ain't got nuffink");
// Do you expect you can re-use the name "v" in both clauses?
if ((var v = o as string) != null) Console.WriteLine(v.Length);
else if ((var v = o as Exception) != null) Console.WriteLine(v.Message);
// Do you expect you can re-use the name "v" in both clauses?
And the way you manually refactor might be effected because if (b) S1 else S2 will no longer mean precisely what if (!b) S2 else S1 means – you might have to do some variable switcharoos (Q3):
if (int.TryParse(s, out int i)) Console.WriteLine("Got integer {0}", i);
else Console.WriteLine("no integer");
// Do you expect you can negate the condition and switch around "then" and "else" clauses?
if (!int.TryParse(s, out int i)) Console.WriteLine("no integer");
else Console.WriteLine("Got integer {0}", i);
The Poll
I’ll hand the results to the team as a non-scientific (because you aren’t randomly chosen) poll, along with any comments you want to make – although if you want to be part of the discussion, this is the place to be. Suggested answers include: yes, no, maybe, don’t care, don’t understand.
Q1: Would you expect a variable declared in the “if” condition to be in scope and available for use in the code of the “else” clause?
Q2: Would you expect to be able to reuse the same variable in multiple “if” clauses that appear as a series of “else if” statements?
Q3: Do you expect to be able to rearrange if and else clauses with no risk of compiler errors regarding out of scope variables?
Q4: Do you think it matters whether C# and Visual Basic.NET do the same thing?
Q5: Are there other scenarios you’re worried or curious about regarding the new declaration expression features?