二十一:构造器之三:类型构造器
类型构造器也称为静态构造器,类构造器,实例构造器是用来初始化类型的实例的初始状态,类型构造器是用来初始化类型的初始状态。一个类型只能定义一个类型构造器,而且不能有参数。 下面代码演示了如何在引用类型和值类型中定义类型构造器:
internal sealed class RefType
{
static RefType()
{
//当RefType第一次被访问的时候执行
}
}
internal struct ValType
{
//C#允许值类型定义无参类型构造器
static ValType()
{
//VarType第一次访问时候执行
}
}
可以看出定义类型构造器用static关键字,C#编译器会自动将类型构造器标记为private,也就是私有的,如果代码中显式的加了访问修改符时编译将不通过。
JIT编译方法时,编译器知道代码引用了什么类型,如果一个类型定义了类型构造器,JIT编译器检查应用程序域是否已经执行了类型构造器,如果从未执行过,JIT编译器将在生成的本地代码中生成一个类型构造器的调用,如果已经执行过了,JIT编译器就不会生成调用代码。
类型构造器只能访问类型的静态字段,而且C#也可以这样初始化字段:
internal sealed class RefType
{
private static Int32 x = 10;
}
internal struct ValType
{
private static Int32 x = 10;
//值类型不允许这样初始化实例字段,把static去掉编译不通过
}
生成上面代码时,编译器自动为它们生成一个类型构造器,查看生成的IL代码,如图:
internal struct ValType
{
private static Int32 x;
static ValType()
{
x = 10;
}
}
internal sealed class RefType
{
private static Int32 x;
static RefType()
{
x = 10;
}
}
再看看以下代码:
internal sealed class RefType
{
public static Int32 x = 5;
static RefType()
{
x = 10;
}
}
在这种情况下,C#编译器生成一个单独的类型构造方法,首先将x初始化为5,接着又将x初始化为10,最后x的值为10,也就是它首先生成初始化静态字段的代码,接着生成类型构造器方法中的显示代码。