为什么包含 ValueTuple 的结构可以满足非托管约束,而 ValueTuple 本身却不能?
How is it that a struct containing ValueTuple can satisfy unmanaged constraints, but ValueTuple itself cannot?
考虑以下类型:
(int, int)
→ 管理。
struct MyStruct { public (int,int) Value; }
→ 不受管理!
问题: 具有托管成员 (int,int)
的非泛型结构 MyStruct
已被评估为托管类型。
预期行为: 包含托管成员的结构应被视为托管,与 struct MyStruct { int? Value; }
被视为托管的方式相同。
示例 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
}
}
Error CS8377 The type '(int, int)' must be a non-nullable value type,
along with all fields at any level of nesting, in order to use it as
parameter 'T' in the generic type or method 'Program.DoSomething()'
示例 2 - 指针或 sizeof
使用上述结构,pointers or sizeof
运算符的行为相同:
unsafe
{
(int, int)* p1; // → Compile-time error,
MyStruct* p2; // → Compiles
}
Error CS0208 Cannot take the address of, get the size of, or declare a
pointer to a managed type('(int, int)')
问题
包含 ValueTuple
的结构如何被视为 unmanaged
并且可以满足 unmanaged
约束,而 ValueTuple
被视为托管?
如何区别对待具有 ValueTupple<T1, T2>
的结构和包含 Nullable<T>
的结构?
注 1: IMO 问题不同于 Proposal: Unmanaged constructed types(由 DavidG 在评论中解决),因为 MyStruct
是不是通用的,另一方面,虽然 int?
和 (int,int)
都是管理的,但 struct MyStruct { int? Value; }
和 struct MyStruct { (int, int) Value; }
的评估不同。
感谢您的报告。这只是编译器中的一个错误。用作字段的元组应注册为通用类型,因此在 unmanaged type
中无效。它似乎正在评估为一个 tulpe 而错过了这个检查。
好消息是,在 C# 8.0 中,此限制将消失。类型 (int, int)
是有效的 unmanaged type
。
考虑以下类型:
(int, int)
→ 管理。struct MyStruct { public (int,int) Value; }
→ 不受管理!
问题: 具有托管成员 (int,int)
的非泛型结构 MyStruct
已被评估为托管类型。
预期行为: 包含托管成员的结构应被视为托管,与 struct MyStruct { int? Value; }
被视为托管的方式相同。
示例 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
}
}
Error CS8377 The type '(int, int)' must be a non-nullable value type, along with all fields at any level of nesting, in order to use it as parameter 'T' in the generic type or method 'Program.DoSomething()'
示例 2 - 指针或 sizeof
使用上述结构,pointers or sizeof
运算符的行为相同:
unsafe
{
(int, int)* p1; // → Compile-time error,
MyStruct* p2; // → Compiles
}
Error CS0208 Cannot take the address of, get the size of, or declare a pointer to a managed type('(int, int)')
问题
包含
ValueTuple
的结构如何被视为unmanaged
并且可以满足unmanaged
约束,而ValueTuple
被视为托管?如何区别对待具有
ValueTupple<T1, T2>
的结构和包含Nullable<T>
的结构?
注 1: IMO 问题不同于 Proposal: Unmanaged constructed types(由 DavidG 在评论中解决),因为 MyStruct
是不是通用的,另一方面,虽然 int?
和 (int,int)
都是管理的,但 struct MyStruct { int? Value; }
和 struct MyStruct { (int, int) Value; }
的评估不同。
感谢您的报告。这只是编译器中的一个错误。用作字段的元组应注册为通用类型,因此在 unmanaged type
中无效。它似乎正在评估为一个 tulpe 而错过了这个检查。
好消息是,在 C# 8.0 中,此限制将消失。类型 (int, int)
是有效的 unmanaged type
。