浅析C#静态类,静态构造函数,静态变量

2019-12-30 12:51:09于海丽

静态变量

静态变量位于栈上,它是一个全局变量,在编译期就已经生成。


public class Cow
{
public static int count;
private int id;
public Cow()
{
id = ++count;
}
}

客户端创建2个Cow的实例,并打印静态变量count。


static void Main(string[] args)
{
Console.WriteLine(Cow.count);
Cow cow1 = new Cow();
Cow cow2 = new Cow();
Console.WriteLine(Cow.count);
} 

结果:

0
2

○ 在创建Cow实例之前,全局就已经有了count这个静态变量
○ 如果在static之前用private修饰,就不可以通过"类名.静态字段名"来访问静态字段,但全局的静态字段始终存在

在堆和栈上的表现,如下图:

 

静态构造函数

在Cow类中添加一个静态构造函数。


public class Cow
{
public static int count;
private int id;
public Cow()
{
id = ++count;
}
static Cow()
{
count = new Random().Next(100);
}
}

在构造函数和静态构造函数中,都对Cow的静态字段赋值。现在我们想了解静态构造函数在什么时候触发。是在用构造函数创建实例的时候触发吗?会不会在设置Cow的字段或属性值的时候触发?在客户端,通过打印静态字段count的值来了解静态构造函数什么时候被触发。


static void Main(string[] args) { Cow cow1 = new Cow(); Console.WriteLine("创建第一个Cow实例后count为:"+ Cow.count); Cow cow2 = new Cow(); Console.WriteLine("创建第二个Cow实例后count为:" + Cow.count); }

○ 静态构造函数在创建第一个Cow实例的时候被触发

○ 在创建第二个Cow实例的时候,静态构造函数没有被触发,而是通过构造函数创建实例

○ 静态构造函数只执行一次

由此,我们是否可以这样定论:静态构造函数是在创建第一个实例时候被触发的?

横看成岭侧成峰,来换个角度思考这个问题。在为类的字段赋值时,会不会触发静态构造函数呢?

把Cow类修改为:


public class Cow
{
public static int count;
private int id;
public static int whatever;
public Cow()
{
id = ++count;
}
static Cow()
{
count = new Random().Next(100);
whatever = count + 10;
Console.WriteLine("静态构造函数被触发后count为:" + Cow.count);
Console.WriteLine("静态构造函数被触发后whatever为:" + Cow.whatever);
}
}

客户端修改为:


static void Main(string[] args)
{
Cow.count = 100;
Cow cow1 = new Cow();
Console.WriteLine("创建第一个Cow实例后count为:"+ Cow.count);
Cow cow2 = new Cow();
Console.WriteLine("创建第二个Cow实例后count为:" + Cow.count); 
}