为什么泛型类型不能有显式布局?

2024-03-30

如果尝试使用以下方法创建一个通用结构[StructLayout http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.structlayoutattribute.aspx(LayoutKind http://msdn.microsoft.com/en-us/library/system.runtime.interopservices.layoutkind.aspx.Explicit)]属性,使用该结构会在运行时生成异常:

System.TypeLoadException:无法从程序集“bar”加载类型“foo”,因为泛型类型不能具有显式布局。

我一直很难找到任何证据证明这种限制确实存在。这Type.IsExplicitLayout http://msdn.microsoft.com/en-us/library/system.type.isexplicitlayout.aspx文档强烈暗示这是允许和支持的。有谁知道为什么这是不允许的?我想不出任何原因为什么泛型类型会使其难以验证。在我看来,这是一个边缘案例,他们根本就懒得去实施。

Here's 一个例子 http://pastebin.com/ZSz37Cu6为什么显式通用布局很有用:

public struct TaggedUnion<T1,T2>
{
    public TaggedUnion(T1 value) { _union=new _Union{Type1=value}; _id=1; }
    public TaggedUnion(T2 value) { _union=new _Union{Type2=value}; _id=2; }

    public T1 Type1 { get{ if(_id!=1)_TypeError(1); return _union.Type1; } set{ _union.Type1=value; _id=1; } }
    public T2 Type2 { get{ if(_id!=2)_TypeError(2); return _union.Type2; } set{ _union.Type2=value; _id=2; } }

    public static explicit operator T1(TaggedUnion<T1,T2> value) { return value.Type1; }
    public static explicit operator T2(TaggedUnion<T1,T2> value) { return value.Type2; }
    public static implicit operator TaggedUnion<T1,T2>(T1 value) { return new TaggedUnion<T1,T2>(value); }
    public static implicit operator TaggedUnion<T1,T2>(T2 value) { return new TaggedUnion<T1,T2>(value); }

    public byte Tag {get{ return _id; }}
    public Type GetUnionType() {switch(_id){ case 1:return typeof(T1);  case 2:return typeof(T2);  default:return typeof(void); }}

    _Union _union;
    byte _id;
    void _TypeError(byte id) { throw new InvalidCastException(/* todo */); }

    [StructLayout(LayoutKind.Explicit)]
    struct _Union
    {
        [FieldOffset(0)] public T1 Type1;
        [FieldOffset(0)] public T2 Type2;
    }
}

usage:

TaggedUnion<int, double> foo = 1;
Debug.Assert(foo.GetUnionType() == typeof(int));
foo = 1.0;
Debug.Assert(foo.GetUnionType() == typeof(double));
double bar = (double) foo;

Edit:

需要明确的是,请注意,即使结构不是通用的,布局也不会在编译时进行验证。 CLR 在运行时检测引用重叠和 x64 差异:http://pastebin.com/4RZ6dZ3S http://pastebin.com/4RZ6dZ3S我问为什么当检查是在运行时以任何一种方式完成时泛型受到限制。


它在 ECMA 335 (CLI),分区 II,第 II.10.1.2 节中指定:

显式:明确提供字段的布局(§II.10.7)。但是,泛型类型不应具有显式布局。

你可以想象它是多么尴尬 - 考虑到类型参数的大小取决于类型参数,你可能会得到一些明显奇怪的效果......引用字段不允许与内置值类型重叠或例如,另一个参考,一旦涉及未知尺寸,就很难保证。 (我还没有研究过 32 位和 64 位参考的效果如何,它们有类似但略有不同的问题......)

我怀疑该规范可以编写为做出一些更详细的限制 - 但使其成为对所有泛型类型的简单全面限制要简单得多。

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

为什么泛型类型不能有显式布局? 的相关文章

  • 将数组向左或向右旋转一定数量的位置,复杂度为 o(n)

    我想编写一个程序 根据用户的输入 正 gt 负 include
  • 从父类调用子类方法

    a doStuff 方法是否可以在不编辑 A 类的情况下打印 B did stuff 如果是这样 我该怎么做 class Program static void Main string args A a new A B b new B a
  • 未解决的包含:“cocos2d.h” - Cocos2dx

    当我在 Eclipse 中导入 cocos2dx android 项目时 我的头文件上收到此警告 Unresolved inclusion cocos2d h 为什么是这样 它实际上困扰着我 该项目可以正确编译并运行 但我希望这种情况消失
  • 为什么#pragma optimize("", off)

    我正在审查一个 C MFC 项目 在某些文件的开头有这样一行 pragma optimize off 我知道这会关闭所有以下功能的优化 但这样做的动机通常是什么 我专门使用它来在一组特定代码中获得更好的调试信息 并在优化的情况下编译应用程序
  • C 预处理器库

    我的任务是开发源分析工具C程序 并且我需要在分析本身之前预处理代码 我想知道什么是最好的图书馆 我需要一些重量轻 便于携带的东西 与其推出自己的 为什么不使用cpp这是的一部分gcc suite http gcc gnu org onlin
  • Json.NET - 反序列化接口属性引发错误“类型是接口或抽象类,无法实例化”

    我有一个类 其属性是接口 public class Foo public int Number get set public ISomething Thing get set 尝试反序列化Foo使用 Json NET 的类给我一条错误消息
  • Cython 和类的构造函数

    我对 Cython 使用默认构造函数有疑问 我的 C 类 Node 如下 Node h class Node public Node std cerr lt lt calling no arg constructor lt lt std e
  • 指针减法混乱

    当我们从另一个指针中减去一个指针时 差值不等于它们相距多少字节 而是等于它们相距多少个整数 如果指向整数 为什么这样 这个想法是你指向内存块 06 07 08 09 10 11 mem 18 24 17 53 7 14 data 如果你有i
  • vector 超出范围后不清除内存

    我遇到了以下问题 我不确定我是否错了或者它是一个非常奇怪的错误 我填充了一个巨大的字符串数组 并希望在某个点将其清除 这是一个最小的例子 include
  • Qt表格小部件,删除行的按钮

    我有一个 QTableWidget 对于所有行 我将一列的 setCellWidget 设置为按钮 我想将此按钮连接到删除该行的函数 我尝试了这段代码 它不起作用 因为如果我只是单击按钮 我不会将当前行设置为按钮的行 ui gt table
  • 从库中捕获主线程 SynchronizationContext 或 Dispatcher

    我有一个 C 库 希望能够将工作发送 发布到 主 ui 线程 如果存在 该库可供以下人员使用 一个winforms应用程序 本机应用程序 带 UI 控制台应用程序 没有 UI 在库中 我想在初始化期间捕获一些东西 Synchronizati
  • 线程睡眠和Windows服务

    我正在开发一个 Windows 服务 该服务存在一些问题Thread Sleep 所以我想我会尝试使用计时器 因为这个问题建议 在 Windows 服务中使用 Thread Sleep https stackoverflow com que
  • 实体框架 4 DB 优先依赖注入?

    我更喜欢创建自己的数据库 设置索引 唯一约束等 使用 edmx 实体框架设计器 从数据库生成域模型是轻而易举的事 现在我有兴趣使用依赖注入来设置一些存储库 我查看了 StackOverflow 上的一些文章和帖子 似乎重点关注代码优先方法
  • 将 xml 反序列化为类,list<> 出现问题

    我有以下 XML
  • C - 直接从键盘缓冲区读取

    这是C语言中的一个问题 如何直接读取键盘缓冲区中的数据 我想直接访问数据并将其存储在变量中 变量应该是什么数据类型 我需要它用于我们研究所目前正在开发的操作系统 它被称为 ICS OS 我不太清楚具体细节 它在 x86 32 位机器上运行
  • const、span 和迭代器的问题

    我尝试编写一个按索引迭代容器的迭代器 AIt and a const It两者都允许更改容器的内容 AConst it and a const Const it两者都禁止更改容器的内容 之后 我尝试写一个span
  • 如何使用 std::string 将所有出现的一个字符替换为两个字符?

    有没有一种简单的方法来替换所有出现的 in a std string with 转义 a 中的所有斜杠std string 完成此操作的最简单方法可能是boost字符串算法库 http www boost org doc libs 1 46
  • ASP.NET MVC 6 (ASP.NET 5) 中的 Application_PreSendRequestHeaders 和 Application_BeginRequest

    如何在 ASP NET 5 MVC6 中使用这些方法 在 MVC5 中 我在 Global asax 中使用了它 现在呢 也许是入门班 protected void Application PreSendRequestHeaders obj
  • 限制C#中的并行线程数

    我正在编写一个 C 程序来生成并通过 FTP 上传 50 万个文件 我想并行处理4个文件 因为机器有4个核心 文件生成需要更长的时间 是否可以将以下 Powershell 示例转换为 C 或者是否有更好的框架 例如 C 中的 Actor 框
  • 恢复上传文件控制

    我确实阅读了以下帖子 C 暂停 恢复上传 https stackoverflow com questions 1048330 pause resume upload in c 使用 HTTP 恢复上传 https stackoverflow

随机推荐

  • SQL 查询获取给定邮政编码 20 英里半径内的所有邮政编码(地址)

    我的查询仅匹配彼此相同的邮政编码 我需要一个查询 可以返回给定邮政编码 20 英里半径内的所有邮政编码 DECLARE cZip VARCHAR 5 SET cZip 63026 DECLARE dMin DECIMAL 20 32186
  • 如何编写参数化sql查询来防止SQL注入?

    当我尝试搜索带有主题标签的术语时 我最初发现这是一个问题 结果发现它是 SQL 中的注释分隔符 搜索没有返回任何结果 因为它忽略了主题标签后面的 term 所以现在我很难找到转义用户输入的正确方法 在我看来 这既可以解决主题标签问题 也可以
  • 需要对这个反复出现的问题有一些了解,ANR keyDispatchingTimedOut

    我有一个应用程序在一个特定组件中不断出现 ANR 但我无法弄清楚是什么占用了 cpu 时间 最近我遇到了两种 ANR 一种是本机的 另一种是等待的 DALVIK THREADS main prio 5 tid 1 NATIVE group
  • 如何获取 Mesos Agents Framework 执行器内存

    在 Mesos Web UI 内部 我可以在表中查看 Spark 执行器的内存使用情况 Agents gt Framework gt Executors 有一个表列出了我的 Spark 驱动程序的所有执行程序 它们的内存使用情况在列中指示M
  • 如何用Java读取PGM图像?

    我觉得我在这里错过了一些简单的东西 像往常一样 我正在尝试使用 Java 读取 PGM 图像 Matlab 做得很好 在 Matlab 中输出图像像素 例如 一个小的 32x32 图像 给我这样的结果 1 0 11 49 94 118 11
  • 如何在 scala 中生成案例类参数的值

    我有一个包含 250 个字段的案例类 case class Data field1 String field2 Int 有没有办法使用 scala check 为其参数生成值 我看过的不相关问题 如何使用宏为 Scala 案例类中的每个字段
  • ViewModel 中的 Thread.CurrentThread.CurrentUICulture 与 Accept-Language

    全球化 提出这个问题的原因是为了更好地理解如何Thread CurrentThread CurrentUICulture与 ViewModel 和控制器中的属性和错误消息相关的工作 我已经设置了我的项目并覆盖OnActionExecutin
  • 使用 PuTTY 的 tail -f 挂起

    我正在使用 PuTTY 命令行连接到服务器并跟踪日志文件 在本地计算机上 我创建了一个文件 tail exec 其中包含以下文本 tail f var log test log 我通过命令行启动腻子 putty ssh t pw m tai
  • MongoDB:如何进行文本搜索并按日期排序

    上下文 我有一个 MongoDB 里面有大量电子邮件 我想搜索包含以下任意字段中给定电子邮件地址的所有电子邮件 收件人 发件人 抄送 和 密件抄送 结果需要按日期字段排序 我们目前正在尝试以下查询 db collection find te
  • 行高向上舍入

    chrome 似乎将计算的值向下舍入line height 例如 line height 1 33 with font size 11px将计算出line height 14px 而确切的值是14 66所以我希望行高等于 15px 您知道是
  • AngularJS ng-value 布尔验证

    具体来说 我有两个单选按钮 它们的 ng model 值必须是布尔值 由于这对于正常的 html value 属性是不可能的 我发现有用的 Angularjs ng value 问题是当我想做一些验证时 当选择单选按钮 ng value f
  • Solr“实时”索引

    我知道有几个与此类似的问题 但它们没有为当前的问题提供简单的答案 抱歉 如果您觉得这是重复的 但我认为清晰易懂的答案将使很多人受益 那么 对于这个问题 Solr 索引更新可以自动化吗 如果可以的话 最佳方法是什么 这是一个简单的用例来澄清问
  • 使用 Powershell 将 PDF 打印为 XPS

    我想使用 Powershell 将包含 PDF 文件的文件夹转换为 XPS 文件 由于系统限制 我无法下载任何第三方软件 例如 iTextSharp 来完成此工作 我已经能够让Powershell打开文档并打开XPS的打印窗口 但名称始终为
  • 使用 javax.sound.midi 包设置乐器通道

    我在 javax sound midi 包中设置乐器时遇到问题 Synthesizer synthesizer MidiSystem getSynthesizer MidiChannel channels synthesizer getCh
  • Python setup.py 在 Egg 中包含 .json 文件

    我想将 json 文件也打包到 python Egg 文件中 例如 boto包有endpoints json文件 但是当我运行 python setup py bdist egg 时 它不包含 Egg 中的 json 文件 如何将Json文
  • greenhills 编译器关闭文件或部分文件的优化

    我发现了几个用于禁用专用代码部分的 GCC 优化的代码片段 使用编译指示 GCC 优化 0 但我找不到 Greenhils 编译器的类似内容 没有这样的选择吗 从手册 pragma ghs Ostring Turns on optimiza
  • Powershell 命令修剪以“\”结尾的路径

    如果路径结尾为 我需要修剪路径 C Ravi 我需要更改为 C Ravi 我有一个情况 路径不会以 那么它必须跳过 我尝试过 EndsWith 但是当我有时它会失败 代替 可以在 PowerShell 中完成此操作而不诉诸条件吗 考虑使用T
  • 检索 Win64 异常表中的所有条目

    从一些更清晰的理解Win64异常堆栈行走不显示条目 https stackoverflow com questions 14187450 win64 exception stack walking not displaying entrie
  • 需要字母和数字 - regEx

    我试图弄清楚如何只需要字母和数字而不需要任何其他字符 所以从字面上看 a z and d or 0 9 取决于对数字执行此操作的更好方法 因此 如果我有一个需要验证的字符串 toValidate Q23AS9D0APQQ2 It may s
  • 为什么泛型类型不能有显式布局?

    如果尝试使用以下方法创建一个通用结构 StructLayout http msdn microsoft com en us library system runtime interopservices structlayoutattribu