C#模式匹配类似于Rust匹配/case,具有解构功能

fdx2calv  于 2022-12-29  发布在  C#
关注(0)|答案(1)|浏览(137)

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#中如何实现这一点?

epggiuax

epggiuax1#

从C# 9.0开始,该语言就支持Pattern Matching,模式语法的概述可以在here中找到。
以此作为参考,很容易在C#中为上述每种情况实现非常相似的功能:

foreach (int n in Enumerable.Range(0, 101)) {
  Console.WriteLine((n % 5, n % 2, n % 7) switch {
    (0, var y, var z) => String.Format("First is `0`, `y` is {0}, and `z` is {1}", y, 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 {0}, and `z` is {1}", y, 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 `new int[] { n % 5, n % 2, n % 7 }`
  Console.WriteLine(new List<int> { n % 5, n % 2, n % 7 } switch {
    [0, var y, var z] => String.Format("First is `0`, `y` is {0}, and `z` is {1}", y, 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",
  });
}

相关问题