Mic*_*tum 8 c# pattern-matching c#-7.0
我正在看C#7的新switch语句,虽然我可以打开类型作为模式匹配的一部分很棒,但我想知道如果我已经知道它可以避免重新说明类型吗?
例:
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;
}
}
Run Code Online (Sandbox Code Playgroud)
在这里,我的case语句重新声明,string x即使我正在打开的类型已经是一个字符串,我只关心它Length,如果它int.TryParse是.
省略它不会编译:
// 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):
Run Code Online (Sandbox Code Playgroud)
所以我只是想知道是否有一种方法可以省略它,或者它只是我必须接受的模式匹配语法的一部分.
你可以使用var模式:
case var x when x.Length == 3 && int.TryParse(x, out int i):
Run Code Online (Sandbox Code Playgroud)
或者甚至更好,var丢弃的模式:
case var _ when s.Length == 3 && int.TryParse(s, out int i):
Run Code Online (Sandbox Code Playgroud)
不,您不能省略类型(或var屏蔽类型的关键字),因为它是此处模式匹配的一部分。
考虑类层次结构(这不会在 中编译C#7,但会在完全实现后在进一步的版本中编译)
class Geometry();
class Triangle(int Width, int Height, int Base) : Geometry;
class Rectangle(int Width, int Height) : Geometry;
class Square(int width) : Geometry;
Run Code Online (Sandbox Code Playgroud)
现在我们得到一个像这样的变量:
Geometry g = new Square(5);
Run Code Online (Sandbox Code Playgroud)
现在我们switch重新做一下:
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;
}
Run Code Online (Sandbox Code Playgroud)
回到你的案例,考虑代码:
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;
}
Run Code Online (Sandbox Code Playgroud)
因此类型检查是模式匹配的一部分,您不能省略它(并且由于C#7它只能用于打开类型,因此计划提供全面支持C#8)。示例是从这里带来的。上一步是异常处理的when子句C#6