模式匹配机制有哪些限制?

Ste*_*Fan 5 c# c#-7.0

就个人而言,我只知道动态不能用于模式匹配,这被认为是一个遗憾:(

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中删除,并已分配以供将来使用.

我不能做的其他事情是什么?

Dav*_*rno 7

C#7中的新模式匹配功能包括以下内容:

  • 支持类型切换,
  • 简单使用var图案,
  • when案件陈述增加了警卫,
  • x is T y图案表达.

您的示例主要关注其中的第一个.类型切换可能是这些新功能中最常用和最常用的.虽然存在一些限制,例如您提到的限制,但其他功能可用于解决其中许多问题.

例如,你的第一个限制是很容易解决的拳击fooobject:

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的模式匹配是它不会让你成为一杯完美的咖啡,或者在几秒钟内将你带到世界各地......但我更愿意回答这个问题的精神.答案真的是唯一的限制是你的想象力.如果你不允许这限制你,那么必须考虑到解决方案具有可读性和/或性能影响这一事实.它们可能是唯一的现实世界限制.