静态构造函数:
基本概念:
静态构造函数用于初始化任何静态数据。
静态构造函数的常见特性:
- 静态构造函数不使用访问修饰符或不具有参数。因为静态构造函数由系统调用,无法人为调用,所以就不存在public、private等。
- 类或结构只能有一个静态构造函数(普通的构造函数可以有多个,因为函数由函数名加参数确定的)。
- 静态构造函数不能继承或重载。
- 静态构造函数不能直接调用,并且仅应由公共语言运行时 (CLR) 调用。 可以自动调用它们。
- 自动调用静态构造函数。将在创建第一个实例或引用任何静态成员之前自动调用静态构造函数。
- 静态构造函数在实例构造函数之前运行。
- 静态字段的初始化会按照在类中的声明顺序执行。 初始值设定项紧接着执行静态构造函数之前运行。
- 静态函数的执行过程是线程私有,不能被其他线程进入
- 静态构造函数最多调用一次
不能出现修饰符:
类的初始化顺序:
本类的静态代码区→父类的静态代码区→父类的实例代码区→本类的实例代码区;
例如:
cs
using System;
class Temp
{
public Temp()
{
Console.WriteLine("Done Temp!");
}
}
class A
{
static A()
{
Console.WriteLine("Done static A()!");
}
public A()
{
Console.WriteLine("Done A()!");
}
}
class B : A
{
static B()
{
Console.WriteLine("Done static B()!");
}
public B()
{
Console.WriteLine("Done B()!");
}
}
class C : B
{
static C()
{
Console.WriteLine("Done static C()!");
}
public C()
{
Console.WriteLine("Done C()!");
}
}
class Run
{
static void Main()
{
/* A a = new A();*/
C c = new C();
Console.ReadLine();
}
}
执行的结果是
在静态代码区中,先执行静态字段的初始化,再执行静态构造函数,不管两者在类内的实现顺序如何;
cs
using System;
class Temp1
{
public Temp1()
{
Console.WriteLine("Done Temp1!");
}
}
class Temp2
{
public Temp2()
{
Console.WriteLine("Done Temp2!");
}
}
class A
{
static A()
{
Console.WriteLine("Done static A()!");
}
private static Temp2 temp2 = new Temp2();
private static Temp1 temp1 = new Temp1();
public A()
{
Console.WriteLine("Done A()!");
}
}
class Run
{
static void Main()
{
A a = new A();
/* C c = new C();*/
Console.ReadLine();
}
}
cs
class A
{
private static Temp2 temp2 = new Temp2();
private static Temp1 temp1 = new Temp1();
static A()
{
Console.WriteLine("Done static A()!");
}
public A()
{
Console.WriteLine("Done A()!");
}
}
修改A类中静态字段和静态构造函数的位置,程序的结果是一样的;
但是修改各个字段的实现位置,结果会发生变化
cs
class A
{
private static Temp1 temp1 = new Temp1();
private static Temp2 temp2 = new Temp2();
static A()
{
Console.WriteLine("Done static A()!");
}
public A()
{
Console.WriteLine("Done A()!");
}
}
实例代码区也是一样的;
个人理解:
类分为静态区和非静态区,静态区包含静态字段,静态方法和静态构造函数;
静态区属于类,而不属于任何类的实例;
参考文档: