浅析C#静态类,静态构造函数,静态变量
静态变量
静态变量位于栈上,它是一个全局变量,在编译期就已经生成。
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#静态类,静态构造函数,静态变量的全部叙述,希望对大家有所帮助!
栏 目:C#教程
下一篇:C# WinForm控件对透明图片重叠时出现图片不透明的简单解决方法
本文标题:浅析C#静态类,静态构造函数,静态变量
本文地址:https://www.xiuzhanwang.com/a1/C_jiaocheng/6473.html
您可能感兴趣的文章
- 01-10C#实现实体类与字符串互相转换的方法
- 01-10C#通过Semaphore类控制线程队列的方法
- 01-10C#3.0使用EventLog类写Windows事件日志的方法
- 01-10C#操作ftp类完整实例
- 01-10winform简单缓存类实例
- 01-10C#实现控制摄像头的类
- 01-10浅析JAVA中过滤器、监听器、拦截器的区别
- 01-10WPF实现类似360安全卫士界面的程序源码分享
- 01-10C#编程自学之数据类型和变量二
- 01-10C#编程自学之数据类型和变量三
阅读排行
本栏相关
- 01-10C#通过反射获取当前工程中所有窗体并
- 01-10关于ASP网页无法打开的解决方案
- 01-10WinForm限制窗体不能移到屏幕外的方法
- 01-10WinForm绘制圆角的方法
- 01-10C#实现txt定位指定行完整实例
- 01-10WinForm实现仿视频播放器左下角滚动新
- 01-10C#停止线程的方法
- 01-10C#实现清空回收站的方法
- 01-10C#通过重写Panel改变边框颜色与宽度的
- 01-10C#实现读取注册表监控当前操作系统已
随机阅读
- 01-10使用C语言求解扑克牌的顺子及n个骰子
- 01-11ajax实现页面的局部加载
- 08-05dedecms(织梦)副栏目数量限制代码修改
- 01-10C#中split用法实例总结
- 08-05织梦dedecms什么时候用栏目交叉功能?
- 04-02jquery与jsp,用jquery
- 01-10SublimeText编译C开发环境设置
- 01-10delphi制作wav文件的方法
- 08-05DEDE织梦data目录下的sessions文件夹有什
- 01-11Mac OSX 打开原生自带读写NTFS功能(图文