• 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修饰,就不可以通过"类名.静态字段名"来访问静态字段,但全局的静态字段始终存在

     

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

    14

      静态构造函数

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

    15

    ○ 静态构造函数在创建第一个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);          
    
            }

    16 

    ○ 在为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();
    
            }

    总结:
    ○ 静态变量属于全局,位于栈上
    ○ 静态构造函数只被触发一次,无论是通过构造函数创建实例,还是给类的字段或属性赋值,静态构造函数的触发时机都在这些动作之前
    ○ 静态类中不能有实例成员

     

     

  • 相关阅读:
    关于java中面向对象特征的总结
    Jemter TCP压测坑:Hex-encoded binary string contains an uneven no. of digits,Hex-encoded binary string contains an uneven no. of digits
    distinct&group by去重的区别
    Idea从gitee上clone项目时候相关问题
    Nginx正向代理
    docker安装MySQL5.7
    Ubuntu server18.04.5环境配置
    Ubuntu18.04.5 server wifi的连接
    git commit 提交规范
    关于js的学习的推介
  • 原文地址:https://www.cnblogs.com/darrenji/p/3976400.html
Copyright © 2020-2023  润新知