ValueTuple 的模式匹配运算符损坏了吗?
Pattern matching operator broken for ValueTuple?
使用 .NET 6
和 C# 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#
基础知识。
更新
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);
}
哪个可能更有用,例如:
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);
}
也就是说,is (...)
模式是 positional pattern and not a type pattern。在位置模式中,我们正在解构对象并将模式应用于它的每个部分,但是指定 d
适用于我们正在应用位置模式的对象,而不是应用于由其部分构造的元组.
我同意当我们只是像您的问题中那样匹配一个元组时,这会让人非常困惑。然而,在我上面的第二个例子中它确实更有意义,其中 c.D
可能是一个复杂的表达式,我们希望能够将它绑定到一个变量,同时也对其应用模式。
实际的 spec 似乎没有涵盖这种情况:它没有指定 simple_designation
是什么类型或它绑定到什么。
使用 .NET 6
和 C# 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#
基础知识。
更新
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);
}
哪个可能更有用,例如:
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);
}
也就是说,is (...)
模式是 positional pattern and not a type pattern。在位置模式中,我们正在解构对象并将模式应用于它的每个部分,但是指定 d
适用于我们正在应用位置模式的对象,而不是应用于由其部分构造的元组.
我同意当我们只是像您的问题中那样匹配一个元组时,这会让人非常困惑。然而,在我上面的第二个例子中它确实更有意义,其中 c.D
可能是一个复杂的表达式,我们希望能够将它绑定到一个变量,同时也对其应用模式。
实际的 spec 似乎没有涵盖这种情况:它没有指定 simple_designation
是什么类型或它绑定到什么。