zoukankan      html  css  js  c++  java
  • 静态初始化(转)


    但要是在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逻辑也能达到效果的话,那肯定郁闷坏了。引用老赵的帖的标题:如果是能简单解决的问题,就不用想得太复杂了

  • 相关阅读:
    Linux中创建Daemon进程的三种方法【转】
    Linux 内核定时器使用 二 高精度定时器 hrtimer 的用例【转】
    使用 Qemu 虚拟 ARM64 平台演示 kdump 崩溃转存【转】
    自旋锁 spin_lock、 spin_lock_irq 以及 spin_lock_irqsave 的区别【转】
    Linux中的spinlock机制[四]
    Linux中的虚拟内存机制和内存映射【转】
    那些情况该使用它们spin_lock到spin_lock_irqsave【转】
    Linux内核中的软中断、tasklet和工作队列详解【转】
    Linux 读写memory操作,devmem直接访问物理内存地址【转】
    Linux性能之DVFS/cpufreq【转】
  • 原文地址:https://www.cnblogs.com/yinxingyeye/p/2442567.html
Copyright © 2011-2022 走看看