就个人而言,我只知道动态不能用于模式匹配,这被认为是一个遗憾:(
dynamic foo = 10;
switch(foo) {
case int i:
break;
}
Run Code Online (Sandbox Code Playgroud)
此外,有价值的元组/新元组不能用于模式匹配:
dynamic foo = (420, 360);
switch(foo) {
case (int, int) i:
break;
}
Run Code Online (Sandbox Code Playgroud)
它已在当前版本的C#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;
}
Run Code Online (Sandbox Code Playgroud)
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;
}
Run Code Online (Sandbox Code Playgroud)
将打印(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;
}
Run Code Online (Sandbox Code Playgroud)
以上将打印(420,360).
对我个人而言,C#7中模式匹配的最大限制是缺少使用关键字的模式匹配表达式match.最初,计划在此版本中使用以下内容,但由于时间限制而被撤销:
var x = 1;
var y = x match (
case int _ : "int",
case * : "other"
);
Run Code Online (Sandbox Code Playgroud)
这可以解决使用switch,但它很乱:
var x = 1;
var y = IntOrOther(x);
...
private string IntOrOther(int i)
{
switch (i)
{
case int _ : return "int";
default: return "other";
}
}
Run Code Online (Sandbox Code Playgroud)
但是有很多第三方模式匹配库的帮助就在这里,例如我自己的Succinc <T>库,你可以把它写成:
var x = 1;
var y = x.TypeMatch().To<string>()
.Caseof<int>().Do("int")
.Else("other")
.Result();
Run Code Online (Sandbox Code Playgroud)
它不如拥有match关键字,但它是一个可选的解决方法,直到该功能出现在更高版本的语言中.
要真正理解C#7所施加的限制,值得参考GitHub上的模式匹配规范,并将其与下一版C#中的模式进行比较.不过看一下,很明显所有这些都有解决方法.
这个问题最初是关闭的,因为它的开放性与目前的措辞一样.举几个愚蠢的例子,限制C#7的模式匹配是它不会让你成为一杯完美的咖啡,或者在几秒钟内将你带到世界各地......但我更愿意回答这个问题的精神.答案真的是唯一的限制是你的想象力.如果你不允许这限制你,那么必须考虑到解决方案具有可读性和/或性能影响这一事实.它们可能是唯一的现实世界限制.