据称,当使用引用类型实例化实例化的泛型类型时,本机代码是共享的,但不是值类型。
为什么?有人会解释深入的细节吗?
更具体:
class MyGenericType {
}
MyGenericType<string> and MyGenericType<Shape>
只生成一个代码,而
MyGenericType<int> and MyGenericType<long>
不会,因此如果使用引用类型更有效则会引发问题 -
MyGenericType<int> vs. MyGenericType<SomeIntegerWrapper>
由于
答案 0 :(得分:3)
首先,要纠正问题中的谬误,int
和System.Int32
是同义词。 MyGenericType<int>
和MyGenericType<Int32>
的类型完全相同。
其次,要解决这个问题(并稍微扩展Mehrdad的答案):考虑一下CLR需要了解的类型。它包括:
对于所有参考类型,这些问题的答案都是相同的。大小只是指针的大小,并且值始终只是一个引用(因此,如果该变量被视为根,则GC需要以递归方式下降到它中)。
对于值类型,答案可能会有很大差异。例如,考虑:
struct First
{
int x;
object y;
}
struct Second
{
object a;
int b;
}
当GC查看某些内存时,需要知道First
和Second
之间的差异,以便它可以递归到y
和a
但不会{{1} }和x
。我相信这些信息是由JIT生成的。现在考虑b
和List<First>
的信息 - 它有所不同,因此JIT需要区别对待两者。
道歉,如果这不是很清楚 - 这是一些很深的东西,我对CLR的细节并不像我那样热。
答案 1 :(得分:1)
从技术上讲,在较低级别,所有引用类型都是指针,因此具有相同的大小和特征。运行时不需要为引用类型构建单独的本机代码。值类型可以有不同的大小,因此单个本机代码无法处理所有这些。