如何使用C#模式匹配元组



我正在尝试切换语句模式匹配,并且我正在寻找一种方法,如果两值元组中的任何一个值为零,则返回false。这是我正在尝试的代码:

static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch(aTuple)
{
case (decimal, decimal) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}

在VSCode 1.47和dotnetcore 3.14中,我得到了一个编译时错误:

CS8652:功能"类型模式"在预览`中

编写此代码的最佳兼容方式是什么?

C# 8中的Type pattern不支持针对形式为(decimal, decimal) t的元组类型进行匹配。但是,我们可以通过指定用于表示C#:中元组的类型ValueTuple来匹配元组类型

public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case ValueTuple<decimal, decimal> t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}

这是演示。


编写代码的另一种方法是使用tuple pattern:

public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case (decimal i1, decimal i2) when i1 == 0 || i2 == 0:
return true;
}
return false;
}

或者我们可以用下一种方式重写这个代码:

public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
// Discards (underscores) are required in C# 8. In C# 9 we will
// be able to write this case without discards.
// See https://github.com/dotnet/csharplang/blob/master/proposals/csharp-9.0/patterns3.md#type-patterns.
case (decimal _, decimal _) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}
return false;
}

此外,我们还可以明确指定匹配值:

public static bool IsAnyValueZero((decimal, decimal) aTuple)
{
switch (aTuple)
{
case (0, _):
return true;
case (_, 0):
return true;
}
return false;
}

这是演示。


C# 9type pattern进行了改进,这样我们就可以使用下一个语法(如您的原始代码示例中所示(来匹配元组类型:

switch (aTuple)
{
// In C# 9 discards (underscores) are not required.
case (decimal, decimal) t when t.Item1 == 0 || t.Item2 == 0:
return true;
}

此功能在C# 9 preview中,并且可以启用。

最新更新