4

I just upgraded my current project to the newly released .NET Standard 2.1 and C# 8.0, and decided to convert some large switch statements into the new, much more compact expression syntax.

Since the returned values are further used in some computations, I was wondering how the new switch expressions behave when the input variable is next to an operator.

Take the following example for string concatenation:

string input = Console.ReadLine();
string output = "Letter: " + input switch
{
    "1" => "a",
    "2" => "b",
    _ => "else"
};
Console.WriteLine(output);

I guess that the switch binds very strongly to the input variable, and thus is evaluated first. And indeed, this prints Letter: a, when I type 1.

But my question now is: Does this behavior apply to any operator?

From my experiments, I was not able to identify a condition where the above hypothesis does not hold, but that obviously does not mean that there isn't a case that I have missed. The docs also don't seem to mention operator precedence in context of switch expressions. Or do I have some deeper misunderstanding here?

Panagiotis Kanavos
  • 120,703
  • 13
  • 188
  • 236
janw
  • 8,758
  • 11
  • 40
  • 62

2 Answers2

5

The Roslyn source suggests that indeed switch expressions have fairly high precedence, but there are some things with higher precedence such as ranges, unary operators, and casts. See here and here in the Roslyn source.

Example code that demonstrates higher precedence of SyntaxKind.LogicalNotExpression (Precende.Unary):

var foo = false;
var bar = !foo switch {
    true => "true",
    false => "false"
};
Console.WriteLine(bar); // writes "true"
Chris Yungmann
  • 1,079
  • 6
  • 14
  • Nice find, didn't have the idea to check out Roslyn's sources directly. I will create an issue to include that into the docs :) – janw Sep 26 '19 at 15:39
1

The Operator precedence doc now (possibly thanks to @janw) has the switch expression listed:

Operators Category or name
x.y, f(x), a[i], x?.y, x?[y], x++, x--, x!, new, typeof, checked, unchecked, default, nameof, delegate, sizeof, stackalloc, x->y Primary
+x, -x, !x, ~x, ++x, --x, ^x, (T)x, await, &x, *x, true and false Unary
x..y Range
switch, with switch and with expressions
... ...
Guru Stron
  • 102,774
  • 10
  • 95
  • 132