Can I simplify this C # 7 switch statement so as not to retype the type?

I am looking at the new C # 7 switch statement, and although it is awesome that I can include this type as part of the pattern matching, I wonder if I can avoid re-specifying the type if I already know it?

Example:

private static void BetterSwitchCase(string s) { switch (s) { case string x when x.Length == 3 && int.TryParse(x, out int i): Console.WriteLine($"s is a string that parses to {i}"); break; default: Console.WriteLine("No Match."); break; } } 

Here is my case re-states string x statement, even if the type that I include is already a string, and I only care about that Length and if it is int.TryParse s.

Just omission does not compile:

 // Syntax error, ':' expected case when s.Length == 3 && int.TryParse(s, out int i): // A constant value is expected case s when s.Length == 3 && int.TryParse(s, out int i): 

So I'm just wondering if there is a way to omit it, or if it's just part of the pattern matching syntax I have to accept.

+7
c # pattern-matching
source share
3 answers

No, you cannot omit the type (or the var keyword, masking the type), since it is part of the template matching here.

Consider a class hierarchy (this will not compile in C#7 , but will compile in future versions after full implementation)

 class Geometry(); class Triangle(int Width, int Height, int Base) : Geometry; class Rectangle(int Width, int Height) : Geometry; class Square(int width) : Geometry; 

Now we get the following variable:

 Geometry g = new Square(5); 

Now we do a switch on it:

 using static System.Console; switch (g) { // check that g is a Triangle and deconstruct it into local variables case Triangle(int Width, int Height, int Base): WriteLine($"{Width} {Height} {Base}"); break; // same for Rectangle case Rectangle(int Width, int Height): WriteLine($"{Width} {Height}"); break; // same for Square case Square(int Width): WriteLine($"{Width}"); break; // no luck default: WriteLine("<other>"); break; } 

Get back to your business, consider the code:

 switch (s) { case string x when x.Length == 3 && int.TryParse(x, out int i): Console.WriteLine($"s is a string that parses to {i}"); break; // will not compile with error // An expression of type string cannot be handled by a pattern of type int. case int x: break; // will win pattern matching and print the line // {s} is an object case object x: Console.WriteLine($"{s} is an object"); default: Console.WriteLine("No Match."); break; } 

So, type checking is part of the pattern matching , and you cannot omit it (and for C#7 it is only available for including types, full support is planned for C#8 ). An example is given from here . The previous step was the when clause for exception handling in C#6

+3
source share

You can use the var template:

 case var x when x.Length == 3 && int.TryParse(x, out int i): 

Or even better, a var pattern with drop:

 case var _ when s.Length == 3 && int.TryParse(s, out int i): 
+7
source share

I used the following. Aesthetically, this is unpleasant, but it has two advantages. This is pretty easy to understand and compile. X is not used. The variable in the switch statement may be a dummy. If you have particularly complex, highly embedded if-then code, this method can be used and it may be easier to read / understand / understand. Does anyone know a better way?

 switch (dummyString) { case string x1 when word = "entry": DoEntry(); break; case string x2 when word = "exit" && door="front": DoFrontDoorExit(); break; case string x3 when word = "exit" && door="rear": DoRearDoorExit(); break; case string x4 when Tomorrow() == "Tuesday": BuyALotteryTicket() break; default: break; } 
0
source share

All Articles