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

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

    public class Cow 
        public static int count; 
        private int id; 
        {
            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
spa

○ 在建立Cow实例以前,全局就已经有了count这个静态变量
○ 若是在static以前用private修饰,就不能够经过"类名.静态字段名"来访问静态字段,但全局的静态字段始终存在
日志

 

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

14

 

  静态构造函数get

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

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

 

在构造函数和静态构造函数中,都对Cow的静态字段赋值。如今咱们想了解静态构造函数在何时触发。是在用构造函数建立实例的时候触发吗?会不会在设置Cow的字段或属性值的时候触发?在客户端,经过打印静态字段count的值来了解静态构造函数何时被触发。it

        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实例的时候,静态构造函数没有被触发,而是经过构造函数建立实例
○ 静态构造函数只执行一次
编译

 

由此,咱们是否能够这样定论:静态构造函数是在建立第一个实例时候被触发的?class

 

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

 

把Cow类修改成:

    public class Cow 
        public static int count; 
        private int id; 
        public static int whatever; 
        {
            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; 
        {
            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; 
        {
            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();
        }

 

 

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

相关文章
相关标签/搜索