考虑以下类型:
-
(int, int)
→ 管理。
-
struct MyStruct { public (int,int) Value; }
→ 不受管理!
Problem:非通用结构MyStruct
,其中有一个托管成员(int,int)
已被评价为托管型。
预期行为:包含托管成员的结构应被视为托管,就像struct MyStruct { int? Value; }
被视为受管理。
看来这两种类型的行为都不符合文档[1] https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/generics/constraints-on-type-parameters?WT.mc_id=DT-MVP-5003235#unmanaged-constraint and [2] https://github.com/dotnet/csharplang/blob/65b8af18a97ff37cae4835b7715c426e81142152/proposals/csharp-7.3/blittable.md#detailed-design.
示例 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)”必须是不可为 null 的值类型,
以及任何嵌套级别的所有字段,以便将其用作
泛型类型或方法“Program.DoSomething()”中的参数“T”
示例 2 - 指针或 sizeof
使用上述结构,行为是相同的pointers https://learn.microsoft.com/en-us/dotnet/csharp/programming-guide/unsafe-code-pointers/pointer-types?WT.mc_id=DT-MVP-5003235 or sizeof https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/operators/sizeof?WT.mc_id=DT-MVP-5003235操作员:
unsafe
{
(int, int)* p1; // → Compile-time error,
MyStruct* p2; // → Compiles
}
错误 CS0208 无法获取地址、获取大小或声明
指向托管类型的指针('(int, int)')
Question
一个结构体如何包含ValueTuple
被认为是unmanaged
并能满足unmanaged
约束,而ValueTuple
是否被视为受管理?
一个结构体如何具有ValueTupple<T1, T2>
和一个包含的结构体Nullable<T>
受到不同对待?
Note 1: IMO the issue is different from the Proposal: Unmanaged constructed types https://github.com/dotnet/csharplang/issues/1504 (addressed by DavidG in comments), because MyStruct
is not generic, on the other hand while int?
and (int,int)
both are managed, but struct MyStruct { int? Value; }
and struct MyStruct { (int, int) Value; }
evaluated differently.