ValueTuple 的模式匹配运算符损坏了吗?

Pattern matching operator broken for ValueTuple?

使用 .NET 6C# 10。考虑这个简单的类型检查:

(object, bool) untyped = new("", false);

if (untyped is (string, bool) typed)
{
    Console.WriteLine(typed.GetType());
}

并且输出:

System.ValueTuple`2[System.Object,System.Boolean]

所以我设法一边吃饼干一边吃。显然,typed变量的类型是(string, bool)and(object, bool).

我正在努力解决这个问题。很想说 “编译器坏了” 但也许我误解了一些 C# 基础知识。

更新

Example code on SharpLab.

IL 不言而喻。

问题

请解释这种类型检查的歧义!模式匹配运算符是否损坏?

认为发生的事情的逻辑是一样的:

if (c is (string, bool) d)
{
    // 'd' is a instance of 'C', not a tuple
}

public class C
{
    public void Deconstruct(out object o, out bool b) => (o, b) = ("", false);
}

SharpLab.

哪个可能更有用,例如:

if (c.D is (string, bool) and { Length: >0 } d)
{
    // 'd' is an instance of 'D'
}

public class C
{
    public D D { get; set; } = new();
}

public class D
{
    public int Length { get; set; }
    public void Deconstruct(out object o, out bool b) => (o, b) = ("", false);
}

SharpLab.

也就是说,is (...) 模式是 positional pattern and not a type pattern。在位置模式中,我们正在解构对象并将模式应用于它的每个部分,但是指定 d 适用于我们正在应用位置模式的对象,而不是应用于由其部分构造的元组.

我同意当我们只是像您的问题中那样匹配一个元组时,这会让人非常困惑。然而,在我上面的第二个例子中它确实更有意义,其中 c.D 可能是一个复杂的表达式,我们希望能够将它绑定到一个变量,同时也对其应用模式。

实际的 spec 似乎没有涵盖这种情况:它没有指定 simple_designation 是什么类型或它绑定到什么。