Yoc*_*mer 28 c# compiler-construction generics jit
我知道泛型是由JIT编译的(就像其他所有东西一样),与编译代码时生成的模板形成对比.
问题是可以使用反射在运行时创建新的泛型类型.
这当然会影响通用的约束.哪个已经通过了语义解析器.
有人能解释一下这是如何处理的吗?究竟发生了什么?
(代码生成和语义检查)
Ani*_*Ani 37
我建议在C#,Java和C++中阅读Generics:与Anders Hejlsberg的对话.
Qn 1.如何通过JIT编译器编译泛型?
从采访中:
Anders Hejlsberg:[...]在CLR [公共语言运行时]中,当您编译List或任何其他泛型类型时,它会像任何普通类型一样编译为IL [中间语言]和元数据.当然,IL和元数据包含知道有类型参数的附加信息,但原则上,泛型类型只编译任何其他类型编译的方式.在运行时,当您的应用程序首次引用List时,系统会查看是否有人已经要求
List<int>
.如果没有,它会向JIT提供IL和元数据List<T>
以及类型参数int.在JITing IL的过程中,JITer也替换了类型参数.[...]
现在,我们接下来要做的是所有类型实例化都是值类型 - 例如
List<int>, List<long>, List<double>, List<float>
-we创建可执行本机代码的唯一副本.所以List<int>
得到自己的代码.List<long>
得到自己的代码.List<float>
得到自己的代码.对于所有引用类型,我们共享代码,因为它们在表示上是相同的.这只是指针.
Qn 2.事情是,可以使用反射在运行时创建新的泛型类型.这当然会影响通用的约束.哪个已经通过了语义解析器.有人能解释一下这是如何处理的吗?
从本质上讲,IL保留了泛型类型的高级视图,它允许CLR在运行时检查"动态构造的"泛型类型的约束,就像C#编译器可能对C#源代码中的"静态构造"类型一样.编译时间.
这是另一个片段(强调我的):
Anders Hejlsberg:[...]有了约束,你可以提升代码的动态检查,并在编译时或加载时验证它.当你说K必须实现IComparable时,会发生一些事情.在类型K的任何值上,您现在可以直接访问接口方法而无需强制转换,因为在程序中语义上它保证它将实现该接口.每当您尝试创建该类型的实例化时,编译器将检查您作为K参数提供的任何类型是否实现IComparable,否则您将收到编译时错误.或者,如果您使用反射进行操作,则会出现异常.
Bruce Eckel:你说的是编译器和运行时.
Anders Hejlsberg:编译器检查它,但您也可以在运行时使用反射进行检查,然后系统检查它.正如我之前所说,在编译时你可以做的任何事情,你也可以在运行时使用反射.
归档时间: |
|
查看次数: |
5038 次 |
最近记录: |