Skip to content

C# 类型构造器

类型构造器 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。

Page Layout Max Width

Adjust the exact value of the page width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the page layout
A ranged slider for user to choose and customize their desired width of the maximum width of the page layout can go.

Content Layout Max Width

Adjust the exact value of the document content width of VitePress layout to adapt to different reading needs and screens.

Adjust the maximum width of the content layout
A ranged slider for user to choose and customize their desired width of the maximum width of the content layout can go.