c#模式匹配模拟Rust match/case的解构



rust中,您可以这样做:

for n in 1..101 {
let triple = (n % 5, n % 2, n % 7);
match triple {
// Destructure the second and third elements
(0, y, z) => println!("First is `0`, `y` is {:?}, and `z` is {:?}", y, z),
(1, ..)  => println!("First is `1` and the rest doesn't matter"),
(.., 2)  => println!("last is `2` and the rest doesn't matter"),
(3, .., 4)  => println!("First is `3`, last is `4`, and the rest doesn't matter"),
// `..` can be used to ignore the rest of the tuple
_      => println!("It doesn't matter what they are"),
// `_` means don't bind the value to a variable
};
}

我如何在c#中做到这一点?

从c# 9.0开始,该语言已经支持模式匹配,模式语法的概述可以在这里找到。

使用这个作为参考,很容易在c#中为上述每种情况实现非常相似的功能:

foreach (int n in Enumerable.Range(0, 101)) {
Console.WriteLine((n % 5, n % 2, n % 7) switch {
(0, var y, var z) => $"First is `0`, `y` is {y}, and `z` is {z}",
(1, _, _) => "First is `1` and the rest doesn't matter",
(_, _, 2)  => "last is `2` and the rest doesn't matter",
(3, _, 4)  => "First is `3`, last is `4`, and the rest doesn't matter",
_      => "It doesn't matter what they are",
});
}

有几点需要特别注意:

  1. 必须使用switch表达式的结果。例如,这会导致一个错误:
foreach (int n in Enumerable.Range(0, 101)) {
// causes: 
//   error CS0201: Only assignment, call, increment, 
//       decrement, await, and new object expressions 
//       can be used as a statement
(n % 5, n % 2, n % 7) switch {
(0, var y, var z) => Console.WriteLine($"First is `0`, `y` is {y}, and `z` is {z}"),
(1, _, _)  => Console.WriteLine("First is `1` and the rest doesn't matter"),
(_, _, 2)  => Console.WriteLine("last is `2` and the rest doesn't matter"),
(3, _, 4)  => Console.WriteLine("First is `3`, last is `4`, and the rest doesn't matter"),
_      => Console.WriteLine("It doesn't matter what they are"),
};
}
  1. 如果我们想使用..来丢弃0或更多位置项,我们需要c# 11.0或更高版本,我们需要将其实例化为Listarray,并切换到使用方括号[]而不是括号(),如下所示:
foreach (int n in Enumerable.Range(0, 101)) {
// this can also be any of: 
//      `new int[] { n % 5, n % 2, n % 7 }`, 
//      `new[] { n % 5, n % 2, n % 7 }`, 
//      `{ n % 5, n % 2, n % 7 }`
Console.WriteLine(new List<int> { n % 5, n % 2, n % 7 } switch {
[0, var y, var z] => $"First is `0`, `y` is {y}, and `z` is {z}",
[1, ..] => "First is `1` and the rest doesn't matter",
[.., 2] => "last is `2` and the rest doesn't matter",
[3, .., 4] => "First is `3`, last is `4`, and the rest doesn't matter",
_ => "It doesn't matter what they are",
});
}

最新更新