考虑以下类型:
看起来这两种类型都违反了文档[1]和[2]的规定。 示例1-非托管约束
错误 CS8377:'(int,int)'类型必须是非可空值类型,以及任何嵌套级别的所有字段,才能将其用作泛型类型或方法'Program.DoSomething()'中的参数。 示例2 - 指针或sizeof 对于上述结构,使用指针或
错误 CS0208 无法获取、大小或声明托管类型的指针('(int, int)')。
问题:
1. 包含 ValueTuple 的结构体如何被视为“非托管”,并且可以满足“非托管”约束条件,而 ValueTuple 被视为托管?
2. 具有 ValueTupple 和包含 Nullable 的结构体如何被区别对待?
(int, int)
→ 托管。struct MyStruct { public (int,int) Value; }
→ 非托管!
MyStruct
,它有一个托管成员(int,int)
,被评估为托管类型。
期望行为:包含托管成员的结构应该被视为托管,就像struct MyStruct { int? Value; }
一样被视为托管。看起来这两种类型都违反了文档[1]和[2]的规定。 示例1-非托管约束
class Program
{
static void DoSomething<T>() where T : unmanaged { }
struct MyStruct { public (int, int) Value; }
static void Main(string[] args)
{
DoSomething<MyStruct>(); // → OK
DoSomething<(int, int)>(); // → Shows compile-time error
}
}
错误 CS8377:'(int,int)'类型必须是非可空值类型,以及任何嵌套级别的所有字段,才能将其用作泛型类型或方法'Program.DoSomething()'中的参数。 示例2 - 指针或sizeof 对于上述结构,使用指针或
sizeof
运算符的行为相同:unsafe
{
(int, int)* p1; // → Compile-time error,
MyStruct* p2; // → Compiles
}
错误 CS0208 无法获取、大小或声明托管类型的指针('(int, int)')。
问题:
1. 包含 ValueTuple 的结构体如何被视为“非托管”,并且可以满足“非托管”约束条件,而 ValueTuple 被视为托管?
2. 具有 ValueTupple 和包含 Nullable 的结构体如何被区别对待?
备注1:我认为这个问题与Unmanaged constructed types提案(由DavidG在评论中解决)不同,因为MyStruct
不是泛型。另一方面,虽然int?
和(int,int)
都是托管的,但struct MyStruct { int? Value; }
和struct MyStruct { (int, int) Value; }
的求值结果是不同的。
DoSomething<MyStruct>()
)视为相同的错误。 - DavidG