能否在动态构造的局部元组上使用C#模式匹配?
问题解答
你的需求完全可以用C#(包括.NET 6/7对应的C# 10/11版本)的语法实现,之前的写法错误是因为没正确掌握模式匹配的规则,下面是修正后的可行写法:
record Thing(List<int> xs, List<int> ys); int DoStuff(Thing thing) { return (thing.xs, thing.ys) switch { // 解构元组并捕获变量,用when子句写条件 (var xs, _) when xs.Count > 5 => xs.First(), (_, var ys) when ys.Count > 5 => ys.Last(), (var xs, var ys) when xs.Count + ys.Count > 5 => xs.First() + ys.Last(), (var xs, var ys) when xs.Count > 0 && ys.Count > 0 => Math.Max(xs.First(), ys.Last()), _ => -1 }; }
错误原因说明
- 你最初的写法直接把布尔表达式(比如
xs.Count >5)放在case位置,这不符合C#模式匹配的语法——switch表达式的case位置必须是模式,而非原始布尔判断。 - 你尝试的
{}属性模式写法有两个问题:(thing.xs, thing.ys)是匿名值元组,元素默认命名为Item1和Item2,不能直接用xs/ys作为属性名;- 属性模式只能匹配单个属性的关系(比如
{Item1.Count: >5}),无法直接处理xs.Count + ys.Count >5这类复合表达式,这类条件需要用when子句补充。
另一种属性模式写法(可读性稍差)
如果想用属性模式,也可以这么写,但不如解构元组直观:
return (thing.xs, thing.ys) switch { { Item1.Count: > 5 } => thing.xs.First(), { Item2.Count: > 5 } => thing.ys.Last(), var t when t.Item1.Count + t.Item2.Count >5 => t.Item1.First() + t.Item2.Last(), { Item1.Count: >0, Item2.Count: >0 } => Math.Max(thing.xs.First(), thing.ys.Last()), _ => -1 };
内容的提问来源于stack exchange,提问作者Mr. Boy
相关产品推荐
相关产品推荐

