编译器会在 C# 中添加默认静态构造函数吗

will the compiler add default static constructor in c#

一般来说,当我们没有显式声明任何构造函数时,编译器会添加默认构造函数。同样,它也默认分配一个静态构造函数。如果没有,为什么?如果是,为什么?在什么情况下?

你和@mjwills 是对的。在没有显式定义实例构造函数的情况下,CLR会自动创建一个see 10.11.4 of the C# language spec.,所以这两个class在IL中是相等的(当然除了名字):

class A1 { }
class A2 { public A2() : base() { } }

您可以像这样检查 class 中是否有任何静态构造函数:typeof(A1).TypeInitializer,或更准确地说 typeof(A1).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).

所以,让我们做一些简单的检查:

class A { }
typeof(A).TypeInitializer == null // true
typeof(A).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 0 // true

class B { static B { } }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

但是,如果您使用一些静态字段或 属性 初始值设定项,CLR 将为您添加一些 "default" 静态构造函数:

class C { public static int I = 1; }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

class D { public static int P { get; set; } = 1; }
typeof(B).TypeInitializer != null // true
typeof(B).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 1 // true

再检查一次没有字段和 属性 初始值设定项:

class E { public static int I; public static int P { get; set; } }
typeof(E).TypeInitializer == null // true
typeof(E).GetConstructors(BindingFlags.Static | BindingFlags.NonPublic).Length == 0 // true

不,C# 中没有自动生成的静态构造函数。

编译器无需创建自动静态构造函数 - 可能需要在静态构造函数中初始化的唯一项目是静态的 fields/properties,但初始化发生在静态构造函数之外。实例构造函数不是这种情况,因为您需要一个构造函数才能创建实例(除非它是静态的 class)-因此如果指定了 none,编译器必须创建一个。

Static field initialzation:

...If a static constructor exists in the class, execution of the static field initializers occurs immediately prior to executing that static constructor. Otherwise, the static field initializers are executed at an implementation-dependent time prior to the first use of a static field of that class.

可以在 Classes section of C# 6.0 draft specification. In particular you can see that Default constructors 中找到更多信息,例如,明确调用自动提供的一个:

If a class contains no instance constructor declarations, a default instance constructor is automatically provided.

Static constructors 没有任何关于它是 "automatically provided" 的信息。

如果您没有为 class 提供构造函数,C# 会默认创建一个实例化对象并将成员变量设置为默认值 Table 中列出的默认值的构造函数。没有任何参数的构造函数称为默认构造函数。换句话说,这种类型的构造函数不带参数。默认构造函数的缺点是 class 的每个实例都将被初始化为相同的值,并且不可能将 class 的每个实例初始化为不同的值。

默认构造函数初始化:

class 中的所有数字字段归零。 所有字符串和对象字段为空。

是。 只有一种情况: 当 class 或结构有一个静态变量被初始化为自定义默认值(比如 static int age=18;)。在这种特殊情况下,默认静态构造函数被添加到 IL 代码中。 除此情况外,将没有默认静态构造函数的作用域。