C# 7 中的新模式匹配功能包括以下内容:
- 支持类型切换,
-
var 模式的简单使用,
- 在 case 语句中添加了
when 保护,
-
x is T y 模式表达式。
您的示例侧重于其中的第一个。而类型切换很可能是这些新功能中最受欢迎和最常用的。虽然存在一些限制,例如您提到的那些限制,但可以使用其他功能来解决其中的许多限制。
例如,您的第一个限制可以通过将foo 装箱object 轻松解决:
dynamic foo = 10;
switch ((object)foo)
{
case int i:
Console.WriteLine("int");
break;
default:
Console.WriteLine("other");
break;
}
将按预期打印int。
var 模式和守卫可用于解决您的第二个限制:
dynamic foo = (420, 360);
switch (foo)
{
case var ii when ii.GetType() == typeof((int, int)):
Console.WriteLine("(int,int)");
break;
default:
Console.WriteLine("other");
break;
}
将打印(int,int)。
另外,值元组可以用于类型切换,你只需要使用长手语法:
var foo = (420, 360);
switch (foo)
{
case ValueTuple<int,int> x:
Console.WriteLine($"({x.Item1},{x.Item2})");
break;
default:
Console.WriteLine("other");
break;
}
上面将打印(420,360)。
就我个人而言,C# 7 中模式匹配的最大限制是缺少使用match 关键字的模式匹配表达式。最初,此版本计划使用以下内容,但为 pulled due to time constraints:
var x = 1;
var y = x match (
case int _ : "int",
case * : "other"
);
这可以使用switch 来解决,但是很麻烦:
var x = 1;
var y = IntOrOther(x);
...
private string IntOrOther(int i)
{
switch (i)
{
case int _ : return "int";
default: return "other";
}
}
但是这里有许多 3rd 方模式匹配库的帮助,比如我自己的 Succinc<T> library,让我们把它写成:
var x = 1;
var y = x.TypeMatch().To<string>()
.Caseof<int>().Do("int")
.Else("other")
.Result();
它不如 match 关键字好,但它是一种可选的解决方法,直到该功能出现在以后的语言版本中。
要真正了解 C# 7 施加的限制,值得参考pattern matching spec on GitHub 并将其与 C# 的下一个版本中的内容进行比较。但仔细观察,很明显所有这些都有变通方法。
这个问题最初是封闭的,因为它按照目前的措辞是开放式的。举几个愚蠢的例子,C# 7 模式匹配的限制是它不会让你喝上一杯完美的咖啡,或者让你在几秒钟内飞过世界……但我更愿意回答这个问题的精神。答案真的是,唯一的限制是你的想象力。如果您不让它限制您,那么必须考虑到变通方法具有可读性和/或性能影响这一事实。它们可能是现实世界中唯一的限制。