当你在C#(或一般的.NET)中使用泛型集合时,编译器基本上是否只需要为特定类型制作泛型集合的腿部工作开发人员。所以基本上。 。 。它只是拯救了我们的工作?
现在我想到了,这不可能是正确的。因为没有泛型,我们以前必须在内部创建使用非泛型数组的集合,因此有装箱和拆箱(如果它是值类型的集合)等等。
那么,在CIL中如何呈现泛型?当我们说我们想要一些通用的东西时,我们在做什么呢?我不一定需要CIL代码示例(虽然这样可以),我想知道编译器如何获取我们的泛型集合并呈现它们的概念。
谢谢!
P.S。我知道我可以使用ildasm来看看这个,但我对CIL看起来仍然像中文,我还没准备好解决这个问题。我只想知道C#(以及我猜其他语言)如何在CIL中渲染以处理泛型的概念。
答案 0 :(得分:14)
答案 1 :(得分:10)
对于值类型,在运行时为每个值类型泛型类定义了一个特定的“类”。对于引用类型,只有一个类定义可以在不同类型中重用。
我在这里进行了简化,但这就是概念。
泛型的设计与实现 NET公共语言运行时
我们的计划大致如下: 当运行时需要特定的时候 实例化参数化 类,加载器检查,看看是否 实例化与任何兼容 它以前见过;如果没有,那么 确定现场布局和新的布局 创建vtable,进行共享 在所有兼容的实例之间。 此vtable中的项目是条目 类的方法的存根。 稍后调用这些存根时, 他们会产生(“及时”) 所有兼容的代码共享 实例。编译时 调用(非虚拟) 特定的多态方法 实例化,我们首先检查一下
如果我们之前编译了这样的电话 对于某些兼容的实例化;如果 不,然后生成一个入口存根, 这将反过来生成代码 共享所有兼容的 实例。两个实例是 兼容if任何参数化 将它的汇编归类于这些 实例化产生了相同的 代码和其他执行结构 (例如现场布局和GC表), 除了描述的词典 见下文第4.4节。特别是, 所有引用类型都是兼容的 彼此,因为装载机 和JIT编译器没有区别 用于现场布局或 代码生成。关于实施 对于Intel x86,至少是原始的 类型互不兼容,甚至 如果他们有相同的大小(fl oats和 int有不同的参数传递 约定)。这留给了用户定义 结构类型,如果是兼容的 他们的布局是相同的 垃圾收集,即他们共享 相同的跟踪指针模式。
http://research.microsoft.com/pubs/64031/designandimplementationofgenerics.pdf