佳佳的博客
Menu
首页
IT
生活
学生
游戏
随机
【C#】类型构造器
IT
C#
《CLR via C#》
2018-05-18
目录
## 类型构造器 type constructor(静态构造器 static constructor) 类型构造器可应用于接口(虽然C#编译器不允许)、引用类型和值类型。 类型构造器的作用是设置类型的初始状态。 类型构造器总是私有的(C#自动把它们标记为 `private`)。 ```cs class SomeRefType { static int MaxCount; static SomeRefType() { MaxCount = 100; } } ``` ## 类型构造器的调用 JIT编译器在编译一个方法时,会查看代码中都引用了哪些类型。 任何一个类型定义了类型构造器,JIT编译器都会检查针对当前 AppDomain,是否已经执行了这个类型构造器。 如果类型构造器从未执行,JIT编译器会在它生成的本机(native)代码中添加对类型构造器的调用。 如果类型构造器已经执行,JIT编译器就不添加对它的调用。 多个线程可能会同时执行到相同的类型构造器方法。 CLR希望确保在每个 AppDomain 中,一个类型构造器只执行一次。 在调用类型构造器时,调用线程要获取一个互斥线程同步锁。 单个线程中的两个类型构造器包含相互引用的代码可能出问题。 如果类型构造器抛出未处理的异常,CLR会认为类型不可用。试图访问该类型的任何字段或方法都会抛出 `System.TypeInitializationException` 异常。 类型构造器中的代码只能访问类型的静态字段,并且它的常规用途就是初始化这些字段。 C#提供了一种简单的语法来初始化类型的静态字段。 ```cs class SomeRefType { static int MaxCount = 50; } ``` 上面的代码相当于 ```cs class SomeRefType { static int MaxCount; static SomeRefType() { MaxCount = 50; } } ``` 如果在静态字段和类型构造器中都赋值的话,以哪个为准呢? ```cs class SomeRefType { static int MaxCount = 50; static SomeRefType() { MaxCount = 100; } } ``` 查看生成的IL代码 ```cs .class /*02000003*/ private auto ansi ConsoleApp1.SomeRefType extends [mscorlib/*23000001*/]System.Object/*01000010*/ { .field /*04000001*/ public static int32 MaxCount .method /*06000003*/ private hidebysig specialname rtspecialname static void .cctor() cil managed // SIG: 00 00 01 { // 方法在 RVA 0x2065 处开始 // 代码大小 16 (0x10) .maxstack 8 IL_0000: /* 1F | 32 */ ldc.i4.s 50 IL_0002: /* 80 | (04)000001 */ stsfld int32 ConsoleApp1.SomeRefType/*02000003*/::MaxCount /* 04000001 */ IL_0007: /* 00 | */ nop IL_0008: /* 1F | 64 */ ldc.i4.s 100 IL_000a: /* 80 | (04)000001 */ stsfld int32 ConsoleApp1.SomeRefType/*02000003*/::MaxCount /* 04000001 */ IL_000f: /* 2A | */ ret } // end of method SomeRefType::.cctor .method /*06000004*/ public hidebysig specialname rtspecialname instance void .ctor() cil managed // SIG: 20 00 01 { // 方法在 RVA 0x205c 处开始 // 代码大小 8 (0x8) .maxstack 8 IL_0000: /* 02 | */ ldarg.0 IL_0001: /* 28 | (0A)000011 */ call instance void [mscorlib/*23000001*/]System.Object/*01000010*/::.ctor() /* 0A000011 */ IL_0006: /* 00 | */ nop IL_0007: /* 2A | */ ret } // end of method SomeRefType::.ctor } // end of class ConsoleApp1.SomeRefType ``` 可以看到只生成了一个 `cctor` (类型构造器)方法,先将 `MaxCount` 赋值为50,然后再赋值为100。
版权声明:原创文章,未经允许不得转载。
https://www.liujiajia.me/2018/5/18/csharp-type-constructor
« 《无双大蛇2:终极版》剧情模式全关卡及人物开启条件
【C#】操作符重载 »
昵称
*
电子邮箱
*
回复内容
*
(回复审核后才会显示)
提交