包含ValueTuple的结构如何满足非托管约束,但ValueTuple本身不能满足? [英] How is it that a struct containing ValueTuple can satisfy unmanaged constraints, but ValueTuple itself cannot?

查看:145
本文介绍了包含ValueTuple的结构如何满足非托管约束,但ValueTuple本身不能满足?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

请考虑以下类型:

  • (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)')

问题

  1. 包含ValueTuple的结构如何被视为unmanaged,并且在ValueTuple被视为托管的情况下如何满足unmanaged约束?

  1. How do a struct containing ValueTuple is considered as unmanaged and can satisfy unmanaged constraint while the ValueTuple 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屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆