使用.NET 6和C# 10。考虑一下这个简单的类型检查:
(object, bool) untyped = new("", false);
if (untyped is (string, bool) typed)
{
Console.WriteLine(typed.GetType());
}以及产出:
System.ValueTuple`2System.Object,System.Boolean
所以我设法吃了饼干,同时吃了它。显然,typed变量是(string, bool)和(object, bool)类型的。
我正试着把头绕在这上面。说“编译器坏了”是很有诱惑力的,但也许我误解了一些C#基本原理。
更新
IL本身就说明了问题。
问题
请解释这种类型的模糊-检查!模式匹配操作符坏了吗?
发布于 2022-04-12 08:35:10
我认为正在发生的事情是逻辑是一样的:
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 (...)模式是位置模式而不是类型模式。在位置模式中,我们正在解构对象并将模式应用于其每个部分,但是d的命名适用于我们要应用位置模式的对象,而不是由其部分构造的元组。
我同意,这是非常混乱的,当我们只是匹配一个元组,如在你的问题。不过,在上面的第二个示例中,这确实更有意义,其中c.D可能是一个复杂的表达式,我们希望能够将其绑定到变量,同时也将模式应用于变量。
实际的等级库似乎没有涵盖这种情况:它没有指定simple_designation是什么类型或绑定到什么类型。
https://stackoverflow.com/questions/71830418
复制相似问题