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

7

我正在尝试使用 switch 语句模式匹配,并且正在寻找一种方法来在两个值的元组中,如果任何一个值为零则返回 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: 该特性 '类型模式' 处于预览状态

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


你的csproj文件中是否有覆盖LangVersion的任何设置?元组模式C# 8.0的一个新特性。 - Paulo Morgado
@PauloMorgado 不。 - eodeluga
这回答您的问题吗?如何在switch语句中使用C#元组值类型 - Mike Nakis
1个回答

14
在C# 8中,Type pattern不支持匹配形式为(decimal, decimal) t的元组类型。但是我们可以通过指定类型ValueTuple来匹配元组类型,该类型用于表示C#中的元组。请注意保留HTML标签,此处无需解释。
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;
}

这里是演示


另一种编写代码的方法是使用元组模式

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# 9类型模式进行了改进,使我们能够使用下一个语法(与您的原始代码示例相同)来匹配元组类型:

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 预览版 中,可以进行 启用


1
谢谢。不过我有点困惑,因为我以为我是按照这篇文章使用 C# 7.0 的特性的。我哪里出错了? https://devblogs.microsoft.com/dotnet/do-more-with-patterns-in-c-8-0/#more-patterns-in-more-places - eodeluga

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接