包含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)
→ managed.struct MyStruct { public (int,int) Value; }
→ unmanaged!
问题:具有托管成员(int,int)
的非通用结构MyStruct
已被评估为托管类型.
Problem: A non-generic structure MyStruct
, which has a managed member (int,int)
has been evaluated as managed type.
预期的行为:包含托管成员的结构应被视为托管,与struct MyStruct { int? Value; }
被视为托管的方式相同.
Expected Behavior: A structure which contains a managed member, should be considered as managed, the same way the struct MyStruct { int? Value; }
are considered as managed.
这两种类型似乎都违反了文档 [1] 和
It seems both types are behaving against the documentations [1] and [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()"中的参数"T"
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
使用上述结构, sizeof
操作符:
Using above structure, the behavior is the same for pointers or sizeof
operator:
unsafe
{
(int, int)* p1; // → Compile-time error,
MyStruct* p2; // → Compiles
}
错误CS0208无法获取其地址,获取其大小或声明一个 指向托管类型的指针('(int,int)')
Error CS0208 Cannot take the address of, get the size of, or declare a pointer to a managed type('(int, int)')
问题
-
包含
ValueTuple
的结构如何被视为unmanaged
,并且在ValueTuple
被视为托管的情况下如何满足unmanaged
约束?
How do a struct containing
ValueTuple
is considered asunmanaged
and can satisfyunmanaged
constraint while theValueTuple
is considered as managed?
具有ValueTupple<T1, T2>
的结构和包含Nullable<T>
的结构如何区别对待?
How a struct having ValueTupple<T1, T2>
and a struct containing Nullable<T>
are treated differently?
注1: IMO,该问题不同于建议:非托管构造类型(在注释中由DavidG解决),因为MyStruct
不是通用的,而同时int?
和(int,int)
都是托管的,而struct MyStruct { int? Value; }
和struct MyStruct { (int, int) Value; }
评估结果不同.
Note 1: IMO the issue is different from the Proposal: Unmanaged constructed types (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.
推荐答案
感谢您的举报.这只是编译器中的一个错误.元组用作字段时应注册为通用类型,因此在unmanaged type
中无效.它似乎被评估为草木,但缺少此检查.
Thanks for reporting. This is just a bug in the compiler. The tuple when used as a field should be registering as a generic type and hence invalid in an unmanaged type
. It appears to be evaluating as a tulpe instead and missing this check.
好消息是,在C#8.0中,此限制将消失.类型(int, int)
是有效的unmanaged type
.
Good news is that in C# 8.0 this restriction will be going away. The type (int, int)
is a valid unmanaged type
.
这篇关于包含ValueTuple的结构如何满足非托管约束,但ValueTuple本身不能满足?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!