为什么包含 ValueTuple 的结构可以满足非托管约束,但 ValueTuple 本身却不能?

2024-04-05

考虑以下类型:

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

  1. 一个结构体如何包含ValueTuple被认为是unmanaged并能满足unmanaged约束,而ValueTuple是否被视为受管理?

  2. 一个结构体如何具有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.


感谢您的报告。这只是编译器中的一个错误。元组用作字段时应注册为通用类型,因此在unmanaged type。它似乎正在作为 tulpe 进行评估,并且缺少此检查。

好消息是,在 C# 8.0 中,此限制将消失。方式(int, int)是一个有效的unmanaged type.

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

为什么包含 ValueTuple 的结构可以满足非托管约束,但 ValueTuple 本身却不能? 的相关文章

  • 解析 JWT 令牌以仅获取有效负载内容,无需 C# 或 Blazor 中的外部库

    我正在使用 Blazor 编写可以访问 JWT 的客户端应用程序 我想知道一种简单的方法来读取令牌有效负载内容而不添加额外的依赖项 因为我不需要其他信息 也不需要验证令牌 我认为解析有效负载内容应该足够简单 只需将其写入方法即可 JwtTo
  • 在 C# 中调用 C++ 库 [关闭]

    Closed 这个问题不符合堆栈溢出指南 help closed questions 目前不接受答案 我有很多用 C 编写的库 我想从 C 调用这些库 但是 我遇到了很多问题 我想知道是否有书籍或指南告诉我如何做到这一点 Dll导入 htt
  • 检测到堆栈崩溃

    我正在执行我的 a out 文件 执行后 程序运行一段时间 然后退出并显示消息 stack smashing detected a out terminated Backtrace lib tls i686 cmov libc so 6 f
  • Gwan C#,如何获取HTTP标头?

    我需要它来重写 url 以了解我正在处理哪个友好的 url 用于用户代理和其他东西 EDIT public class Gwan MethodImplAttribute MethodImplOptions InternalCall exte
  • 如何制作可启动程序?

    所以 这个问题可能看起来很奇怪 但假设我编译了 int main void int x 3 int y 4 int z x y 是否可以让CPU这样运行 如何 例如 这允许我写入监视器吗 如果我没记错的话 内存中有些地方可以写入要显示的内容
  • C# 5 async/await 线程机制感觉不对?

    为什么让调用线程进入异步方法直到内部 等待 一旦调用异步方法就生成一个线程 这不是更干净吗 这样您就可以确定异步方法会立即返回 您不必担心在异步方法的早期阶段没有做任何昂贵的事情 我倾向于知道某个方法是否要在 我的 线程上执行代码 不管是堵
  • 计算另一个表达式中的 C# 表达式

    我想在另一个表达式中使用一个表达式 Expression
  • 为什么'enable_if'不能用于禁用这里声明

    include
  • 将表(行)与 OpenXML SDK 2.5 保持在一起

    我想在 Word 文档中生成多个表 每行 2 行 但我想将这两行保留在一起 如果可能的话 new KeepNext 第一行不起作用 new KeepNext 第一行的最后一段不起作用 new CantSplit 放在桌子上不起作用 在所有情
  • 根据对象变量搜索对象列表

    我有一个对象列表 这些对象具有三个变量 ID 名称和值 这个列表中可能有很多对象 我需要根据ID或Name找到一个对象 并更改值 例子 class objec public string Name public int UID public
  • UI 函数在快速事件完成之前触发

    我有一个停靠在 Silverlight 应用程序中的 Web 浏览器框架 有时会在其上弹出全窗口 XAML Silverlight UI 元素 我已经或多或少修复了一个老问题 即 Web 框架的内容似乎与 Silverlight 内容不能很
  • 如何在三个 IEnumerable 上使用 Zip [重复]

    这个问题在这里已经有答案了 可能的重复 使用 Linq 从 3 个集合创建项目 https stackoverflow com questions 5284315 create items from 3 collections using
  • 搜索实体的所有字段

    我正在尝试在客户数据库上实现 多功能框 类型的搜索 其中单个查询应尝试匹配客户的任何属性 这是一些示例数据来说明我想要实现的目标 FirstName LastName PhoneNumber ZipCode Mary Jane 12345
  • Java:一个函数有多种返回类型...可以使用泛型吗?

    为了简单起见 我有一些程序 如下所示 public String fetchValueAsString String key public DateTime fetchValueAsDateTime String key 我想要类似的东西
  • CUDA 8 编译错误 -std=gnu++11

    我正在尝试转换一些代码以使用 CUDA 并且我认为我遇到了兼容性问题 我们使用CMake 这些是我使用的 gcc 和 CUDA 版本 gcc version gcc Ubuntu 5 4 0 6ubuntu1 16 04 5 5 4 0 2
  • 通过 Tab 键浏览 XML 文档字段

    In VB NET you can move through the fields in the XML member documentation with the Tab key 这在 C 中不起作用 还有其他方法吗 除了用鼠标将光标放在
  • 使用 using 声明时,非限定名称查找如何工作?

    根据 C 标准 这是格式错误还是格式良好 namespace M struct i namespace N static int i 1 using M i using N i int main sizeof i Clang 拒绝它 GCC
  • INotifyPropertyChanged 和 propertyName

    我一直不确定它的含义propertyName实施时INotifyPropertyChanged 所以一般来说你实现INotifyPropertyChanged as public class Data INotifyPropertyChan
  • 结构化绑定的用例有哪些?

    C 17 标准引入了新的结构化绑定 http en cppreference com w cpp language structured binding功能 最初是proposed http www open std org jtc1 sc
  • 使用未分配的局部变量

    我遇到了一个错误 尽管声明了变量 failturetext 和 userName 错误仍然出现 谁能帮帮我吗 Use of Unassigned local variable FailureText Use of Unassigned lo

随机推荐