欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

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

程序员文章站 2022-05-28 18:45:03
静态变量 静态变量位于栈上,它是一个全局变量,在编译期就已经生成。 public class cow { public static int count...

静态变量

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

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); 
} 

○ 在为cow的字段赋值之前,静态构造函数被触发

○ 接着创建cow实例,静态构造函数不会被再次触发

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

到这里,关于静态构造函数被触发的时机,我们可以这样下结论:无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数是在所有这些动作之前被触发的。

静态类

首先创建一个类,包括静态成员和非静态成员。

public class logger
{ private static int lognumber = 0;
static public void initializelogging()
{
console.writeline("日志初始化");
}
static public void closelog()
{
console.writeline("日志关闭");
}
static public void logmsg(string msg)
{
console.writeline("日志编号为:" + lognumber + ":" + msg);
}
public void dosth()
{
console.writeline("我不是静态方法~~");
}
}

在客户端,既可以通过"类名.静态方法名称"调用方法,也可以通过类的实例调用方法。

static void main(string[] args)
{
logger.initializelogging();
logger.logmsg("日志被记录下了~~");
logger.closelog();
logger logger = new logger();
logger.dosth();
}

如果把一个类设置成静态类,意味着:这个类的所有一切存在于栈上,因此该类中不能有实例方法,也不能创建该类实例。

修改logger类,把实例方法去掉。

public static class logger
{
private static int lognumber = 0;
static public void initializelogging()
{
console.writeline("日志初始化");
}
static public void closelog()
{
console.writeline("日志关闭");
}
static public void logmsg(string msg)
{
console.writeline("日志编号为:" + lognumber + ":" + msg);
}
}

在客户端,更不能创建logger的实例,只能通过"类名.静态方法名"调用方法。

static void main(string[] args)
{
logger.initializelogging();
logger.logmsg("日志被记录下了~~");
logger.closelog();
} 

总结:

○ 静态变量属于全局,位于栈上

○ 静态构造函数只被触发一次,无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数的触发时机都在这些动作之前

○ 静态类中不能有实例成员

以上内容是小编给大家介绍的c#静态类,静态构造函数,静态变量的全部叙述,希望对大家有所帮助!