在Rust中有一个名为match
的便捷语句。它与switch
类似,但可能有多个变量。
以下是使用此技术进行fizz-buzz的伪示例:
match (i % 3 == 0, i % 5 == 0) {
(false, false) => { // },
(true, true) => { // FizzBuzz },
(true, false) => { // Fizz },
(false, true) => { // Buzz }
}
是否可以使用C#7进行相同或类似的操作?
答案 0 :(得分:3)
我会在C#7中使用元组语法:
class Program
{
enum FizzBuzz
{
None,
Fizz,
Buzz,
FizzBuzz
}
static void Main(string[] args)
{
// Declare the map
Dictionary<(bool, bool), FizzBuzz> matchMap =
new Dictionary<(bool, bool), FizzBuzz>
{
{ (false, false), FizzBuzz.None },
{ (true, true), FizzBuzz.FizzBuzz },
{ (true, false), FizzBuzz.Fizz },
{ (false, true), FizzBuzz.Buzz },
};
// Demonstration of the map
for (int i = 0; i < 16; i++)
{
Console.WriteLine($"i: {i}, (i % 3 == 0, i % 5 == 0): {matchMap[(i % 3 == 0, i % 5 == 0)]}");
}
}
}
目前,您需要使用NuGet包管理器将ValueTuple
包添加到项目中以进行编译。 ValueTuple
类型实现了适当的相等比较,以允许字典工作。
答案 1 :(得分:1)
感谢@PeterDuniho指出了实现这项工作的方法。以下代码(虽然不像锈色代码那样简洁和干净)在C#7中有效。
(None,1)
您可以使用这样的逻辑快捷键来缩短上述内容:
switch((i % 3 == 0, i % 5 == 0))
{
case ValueTuple<bool, bool> t when (t.Item1 == true && t.Item2 == true):
// FizzBuzz
break;
case ValueTuple<bool, bool> t when (t.Item1 == true && t.Item2 == false):
// Fizz
break;
case ValueTuple<bool, bool> t when (t.Item1 == false && t.Item2 == true):
// Buzz
break;
}
这样可行,因为如果前一个参数为假,它只能评估第二个和第三个参数。当然,这只适用于像这样的简单布尔情况。
此外,我对此处的财产评估持谨慎态度,并附带副作用。你不应该设计具有副作用的属性,但如果你这样做,可能会多次评估属性,导致副作用多次应用(即,说你的属性每次增加或减少一个值&# 39; s叫。)
答案 2 :(得分:0)
在C#7中,您可以使用ValueTuple
编写一个扩展方法来或多或少地使用LINQ伪造该语法:
class Program
{
static void Main()
{
var fb =
Enumerable.Range(0, 20)
.Select(n => ((n % 3 == 0), (n % 5 == 0)))
.Match(
((true, true), () => "FizzBuzz"),
((true, false), () => "Fizz"),
((false, true), () => "Buzz")
);
Console.WriteLine(String.Join("\n", fb));
Console.ReadKey();
}
}
public static class Extensions
{
public static IEnumerable<TResult> Match<TInput, TResult>(
this IEnumerable<TInput> e,
params ValueTuple<TInput, Func<TResult>>[] cases)
{
return
from evalue in e
join @case in cases on evalue equals @case.Item1
select @case.Item2();
}
}
我质疑任何在生产代码中这样做的人的理智,但我会在下次面试时牢记这一点。
或者你可以回到旧石器时代:
switch ((n % 3 == 0 ? 1 : 0) | ((n % 5 == 0) ? 2 : 0))
{
case 1:
//"Fizz";
break;
case 2:
//"Buzz";
break;
case 3:
//"FizzBuzz";
break;
}
答案 3 :(得分:0)
使用ValueTuple
添加到@ ErikFunkenbusch的{{3}},我们可以进一步利用此功能按名称访问ValueTuple
个项目,而不是使用Item1
,{{1等等:
Item2