为参考类型原因和效率含义共享通用代码

时间:2009-02-28 21:21:05

标签: c# .net generics

据称,当使用引用类型实例化实例化的泛型类型时,本机代码是共享的,但不是值类型。

为什么?有人会解释深入的细节吗?

更具体:

class MyGenericType {

}

 MyGenericType<string> and MyGenericType<Shape>

只生成一个代码,而

 MyGenericType<int> and MyGenericType<long> 

不会,因此如果使用引用类型更有效则会引发问题 -

MyGenericType<int> vs. MyGenericType<SomeIntegerWrapper>

由于

2 个答案:

答案 0 :(得分:3)

首先,要纠正问题中的谬误,intSystem.Int32是同义词。 MyGenericType<int>MyGenericType<Int32>的类型完全相同。

其次,要解决这个问题(并稍微扩展Mehrdad的答案):考虑一下CLR需要了解的类型。它包括:

  • 该类型值的大小(即,如果您有某种类型的变量,该内存需要多少空间?)
  • 如何根据垃圾收集处理该值:它是对对象的引用,还是可能包含其他引用的值?

对于所有参考类型,这些问题的答案都是相同的。大小只是指针的大小,并且值始终只是一个引用(因此,如果该变量被视为根,则GC需要以递归方式下降到它中)。

对于值类型,答案可能会有很大差异。例如,考虑:

struct First
{
    int x;
    object y;
}

struct Second
{
    object a;
    int b;
}

当GC查看某些内存时,需要知道FirstSecond之间的差异,以便它可以递归到ya但不会{{1} }和x。我相信这些信息是由JIT生成的。现在考虑bList<First>的信息 - 它有所不同,因此JIT需要区别对待两者。

道歉,如果这不是很清楚 - 这是一些很深的东西,我对CLR的细节并不像我那样热。

答案 1 :(得分:1)

从技术上讲,在较低级别,所有引用类型都是指针,因此具有相同的大小和特征。运行时不需要为引用类型构建单独的本机代码。值类型可以有不同的大小,因此单个本机代码无法处理所有这些。