就个人而言,我只知道动态不能用于模式匹配,这被认为是一种遗憾:(
dynamic foo = 10;
switch(foo) {
case int i:
break;
}
此外,有价值的元组/新元组不能用于模式匹配:
dynamic foo = (420, 360);
switch(foo) {
case (int, int) i:
break;
}
它已在当前版本的C#7中删除,并已分配以供将来使用。
我不能做的其他事情是什么?
答案 0 :(得分:7)
C#7中的新模式匹配功能包括以下内容:
var
模式,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";
}
}
但是这里有许多第三方模式匹配库,例如我自己的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的模式匹配是它不会让你成为一杯完美的咖啡,或者在几秒钟内将你带到世界各地......但我更愿意回答这个问题的精神。答案真的是唯一的限制是你的想象力。如果你不允许这限制你,那么必须考虑到解决方案具有可读性和/或性能影响这一事实。它们可能是唯一的现实世界限制。