2011-07-20 16 views
5

如果我编写(或使用)泛型类,例如列出并使用两种不同枚举类型对其进行参数化,我会得到两个JITted代码副本吗?鉴于以下文章讨论了JI​​Tter如何为引用类型生成一个副本,并为每个值类型生成了一个副本,我认为这归结为:“为了JITting的目的,每个特定的枚举都被视为不同的值类型?.NET JIT编译器是否为不同的枚举生成了泛型参数化的不同代码?

CLR vs JIT

http://msdn.microsoft.com/en-us/library/ms379564%28v=vs.80%29.aspx#csharp_generics_topic1

在C#代码:

using System.Collections.Generic; 

namespace Z 
{ 
    class Program 
    { 
     enum A {a} 
     enum B {b} 
     class C<T> 
     { 
     } 

     static void Main(string[] args) 
     { 
      var x = new C<A>(); 
      var y = new C<B>(); // does this JIT a new C constructor for enum type B? 
     } 
    } 
} 

我想知道这在一般情况下,还专门为.NET CF 3.5(Windows CE的)JIT编译器(编辑:因为我对可能的代码膨胀影响感兴趣)。有什么建议可以找到最好的方法?我正在考虑在C类中编写一个函数,将P /调用到本地代码中,我可以打开调试器并检查callstack - 特别是返回地址,但也许有人可以根据语言规则进行权威性回答, m不知道...

+2

我猜测每个底层整型只有一个实例化,但我很乐意听到权威的答案。 –

+2

是的。我们应该添加哪些标签来吸引Eric Lippert的注意力? – 2011-07-20 21:53:14

+0

'fabulous-adventures-in-coding',我认为 –

回答

5

因此,我继续前进,并提出一个P/Invoke函数来调用一个C <T>。测试函数。我在本地函数中插入了调试器(支持托管调试和本地调试的桌面窗口),然后放到程序集中,然后从我的本地函数中追踪RET指令。 RET之后的EIP(指令指针)与返回到两个不同的例程一致,一个用于C <A>。测试,另一个用于C <B>。测试。通过这两个函数对通用原生函数(通过我的断点)进行多次调用显示了一致的结果。此外,后RET EIPs是0x2E0246和0x2E02BE,它们彼此靠近,也没有映射到加载的DLL的地址空间。这表明它们被打乱了,并且在时间上彼此靠近,并且JITted方法的大小很小(如预期的那样)。

因此,至少对于桌面系统来说,答案是泛型以不同的例程模板化了不同的枚举JIT。

相关问题