为什么泛型中的值类型参数不共享本机代码

本文关键字:共享 本机代码 类型参数 泛型 为什么 | 更新日期: 2023-09-27 18:03:46

为了避免泛型中的代码爆炸,CLR认为所有引用类型参数都是相同的,以便代码可以共享(CLR可以执行这种优化,因为所有引用参数或变量实际上只是指针)。但是,如果任何类型参数都是值类型,则不会发生这种情况而给出的理由是"值类型可以改变大小"。

所以我的问题是值类型有什么特别之处,它使它的大小不同,这与本机代码不共享值类型参数有什么关系?

为什么泛型中的值类型参数不共享本机代码

假设你有两个类

class C1
{
    public int I1;
}
class C2
{
    public int I1;
    public int I2;
    public int I3;
}

C1类型的变量与C2类型的变量具有相同的大小。因为类是引用类型,所以这些变量的大小就是引用的大小,总是相同的常量。


现在让我们看一个类似的场景,但是使用结构体:

struct S1
{
    public int I1;
}
struct S2
{
    public int I1;
    public int I2;
    public int I3;
}

注意,struct是值类型,而不是引用类型

S1类型变量的大小与S2类型变量的大小不同。

S1类型变量的大小= sizeof(I1)
S2类型变量的大小= sizeof(I1) + sizeof(I2) + sizeof(I3)

(实际上,根据结构体成员的类型,如果编译器出于与内存访问性能相关的原因决定向结构体添加填充字节,那么结构体的大小可能会稍微大一些。但由于这与这里的解释无关,我建议您忽略这个问题中的填充。


当然,这不仅仅局限于变量,对于字段和属性类型以及方法参数也是如此。

想象一下,您创建了自己的泛型类:

class MyGeneric<T>
{
    public void DoSomething(T parameter)
    {...}
}

使用上面定义的结构体(S1和S2),那么很明显,MyGeneric<S1>类的DoSomething方法的参数"parameter"与MyGeneric<S2>类的相同参数的大小不同。