• 静态初始化(转)



    但要是在Main()里添加一行:

    C#代码 复制代码 收藏代码
    1. using System;   
    2.   
    3. public class Singleton {   
    4.     public static Singleton Instance = new Singleton();   
    5.   
    6.     private Singleton() {   
    7.         Console.WriteLine("Singleton()");   
    8.     }   
    9. }   
    10.   
    11. static class Program {   
    12.     static void Main(string[] args) {   
    13.         Console.WriteLine("Main()");   
    14.         var s = Singleton.Instance;   
    15.         Console.WriteLine("leaving Main()");   
    16.     }   
    17.   
    18.     static void Foo() {   
    19.         var s = Singleton.Instance;   
    20.     }   
    21. }  
    using System;
    
    public class Singleton {
        public static Singleton Instance = new Singleton();
    
        private Singleton() {
            Console.WriteLine("Singleton()");
        }
    }
    
    static class Program {
        static void Main(string[] args) {
            Console.WriteLine("Main()");
            var s = Singleton.Instance;
            Console.WriteLine("leaving Main()");
        }
    
        static void Foo() {
            var s = Singleton.Instance;
        }
    }


    输出结果跟想像的可能就不一样了:

    引用
    Singleton()
    Main()
    leaving Main()


    这是因为C#中直接在静态变量声明的地方就初始化,而且没有显式提供静态构造器实现的话,会使类带上beforefieldinit标记,使得类的静态初始化提早执行。稍微改改,给Singleton类添加一个空的静态构造器的话……

    C#代码 复制代码 收藏代码
    1. using System;   
    2.   
    3. public class Singleton {   
    4.     public static Singleton Instance = new Singleton();   
    5.   
    6.     static Singleton() {   
    7.     }   
    8.   
    9.     private Singleton() {   
    10.         Console.WriteLine("Singleton()");   
    11.     }   
    12. }   
    13.   
    14. static class Program {   
    15.     static void Main(string[] args) {   
    16.         Console.WriteLine("Main()");   
    17.         var s = Singleton.Instance;   
    18.         Console.WriteLine("leaving Main()");   
    19.     }   
    20.   
    21.     static void Foo() {   
    22.         var s = Singleton.Instance;   
    23.     }   
    24. }  
    using System;
    
    public class Singleton {
        public static Singleton Instance = new Singleton();
    
        static Singleton() {
        }
    
        private Singleton() {
            Console.WriteLine("Singleton()");
        }
    }
    
    static class Program {
        static void Main(string[] args) {
            Console.WriteLine("Main()");
            var s = Singleton.Instance;
            Console.WriteLine("leaving Main()");
        }
    
        static void Foo() {
            var s = Singleton.Instance;
        }
    }


    会发现执行结果变为:

    引用
    Main()
    Singleton()
    leaving Main()


    这种写法就不会使类带上beforefieldinit,于是初始化时间就跟“想像中”的一样,哪儿用到哪儿才初始化。把Instance的初始化整个挪到静态构造器里的结果也一样。

    有时候费了力气去写个double-check搞不好还写错了,要是回头发现其实不用自己费神写lazy逻辑也能达到效果的话,那肯定郁闷坏了。引用老赵的帖的标题:如果是能简单解决的问题,就不用想得太复杂了

  • 相关阅读:
    【Windows】Windows server2008远程桌面只允许同时存在一个会话
    【go进阶】一个简单的go服务器实现
    【linux杂谈】查看centOS系统的版本号和内核号
    【linux杂谈】centos6和centos7中固定IP的方法
    Eclipse导入GitHub项目(转)
    国际锐评
    Spring Boot与分布式
    Spring Boot与分布式
    springboot 与任务
    废掉一个人最隐蔽的方式,是让他忙到没时间成长(转)
  • 原文地址:https://www.cnblogs.com/yinxingyeye/p/2442567.html
Copyright © 2020-2023  润新知