C# 这两个构造函数做的是相同的事情吗?

C# 这两个构造函数做的是相同的事情吗?,c#,static-constructor,C#,Static Constructor,这两个代码块做的是相同的事情吗 class A { public static int s; A(){} static A(){s = 100;} } 及 他们做同样的事情吗?我想是的。不,他们的行为方式不太一样。如果没有静态构造函数,则类型初始值设定项执行的确切时间就要宽松得多——它可能比您预期的更早或更晚 当存在静态构造函数时,类型初始值设定项在类型首次用于访问任何静态成员或创建任何实例时执行 当没有静态构造函数时,唯一的保证是初始值设定项将在第一次访问静态字段之前的某个

这两个代码块做的是相同的事情吗

class A {
   public static int s;
   A(){}
   static A(){s = 100;}
}


他们做同样的事情吗?我想是的。

不,他们的行为方式不太一样。如果没有静态构造函数,则类型初始值设定项执行的确切时间就要宽松得多——它可能比您预期的更早或更晚

当存在静态构造函数时,类型初始值设定项在类型首次用于访问任何静态成员或创建任何实例时执行

当没有静态构造函数时,唯一的保证是初始值设定项将在第一次访问静态字段之前的某个时间点执行(仍然只执行一次)。根据JIT的不同,这可能意味着它执行得很早(例如,当您第一次执行可能使用成员的方法时)或很晚(在调用不使用任何字段的静态成员后,或在创建和使用实例后)

在IL中,区别在于没有静态构造函数的类型具有标志;有静态构造函数的则不然。

效果相同,但实际执行顺序可能不同。当存在静态构造函数时,静态字段在调用构造函数或访问任何静态字段之前立即初始化。如果没有静态构造函数,那么可以在首次使用某个静态字段之前的任何时间执行字段初始值设定项


由于您的初始值设定项没有副作用,也不能抛出异常,因此这两者之间不会有任何明显的区别,除非使用反射或其他外部观察者(例如调试器)

除了一些边缘情况,例如行为,是的,它们做相同的事情。事实上,两种情况下编译的IL几乎相同。唯一的区别是在没有静态构造函数的函数上存在beforefieldinit

class A
{
    public static int s;
    A() { }
    static A() { s = 100; }
}

class B
{
    public static int s = 100;
    B() { }
}
编译成

.class private auto ansi A
    extends [mscorlib]System.Object

.class private auto ansi beforefieldinit B
    extends [mscorlib]System.Object

使用相同的方法/字段定义。

根据C#简而言之,静态构造函数在您第一次使用属性时执行,最常用的用法是当您想要计算或读取一些数据并设置为静态属性时(如appconfig.config中的密码)。在不使用静态构造函数的情况下,您必须定义一个Init方法,并在应用程序启动时调用它。

两个
s
的实例都将是100,是的。在这种情况下,它们将在事后生成相同的结果,只需以不同的方式执行。请尝试使用搜索并共享您找到的内容。这里重复的所有答案以前都解释过。请看,不完全是这样:当存在静态构造函数时,它就在调用构造函数或任何静态成员之前。如果没有静态构造函数,则在访问静态字段之前-使用实例字段不必触发初始值设定项。如果两个选项都可以,您通常会选择哪一个,有没有静态构造函数定义?@LucaCremonesi:通常我会选择更清晰的定义——通常没有静态构造函数,除非我在初始化方面做了大量工作(这通常是一种设计味道)。
.class private auto ansi A
    extends [mscorlib]System.Object

.class private auto ansi beforefieldinit B
    extends [mscorlib]System.Object