• static的初始化顺序 (转)


    先看个例子:

    using System;

    Class A
    {
     static int X;
     static A()
     {
      X = B.Y + 1;
     }
    }

    Class B
    {
     public static int Y = A.X + 1;
     static B() {}
     
     static void Main()
     {
      Console.WriteLine("X={0},Y={1}",A.X,B.Y); 
      }

    }

    执行结果是X=1,Y=2

    这个例子主要考查2个方面,一是static的用法,二是static的初始化顺序。了解了static的初始化顺序和规则,这个问题答答案就很容易理解了。这里涉及到以下三类static对象:static成员,static方法,static构造函数。规则如下:

    一个类的static构造函数在给定的应用程序域中仅执行一次。static构造函数由在应用程序域的下列事件的首次发生时触发:
    1)该类的实例被创建。
    2)任何一个static成员被引用
    3)如果类包含执行入口Main方法,此类的static构造函数在Main方法被调用之前执行。
    4)如果类包含任何staic成员,则这些static成员在static构造函数之前进行初始化。
    5)如果类包含任何static方法,则这些static方法在static构造函数之后进行初始化。
    6)对于存在多个static成员,他们的初始化将按照文本顺序进行,不会因为调用顺序而改变。

    现在看看上面的应用程序,Class B中有个Main执行入口,所以B首先得到初始化,顺序是static成员Y->static构造函数。在初始化Y时,引用了A.X,编译器又开始初始化Class A(注意这时Class B的初始化并没有完成),顺序也是static成员X->static构造函数。Class A中X在定义的时候没有被赋予初始值(在定义static变量时,尽量赋予初始值),编译器会默认赋予值0(int型)。然后再执行static的构造函数,由于Class B的初始化这时还没有完成,所以B.Y的值在这时被编译器赋予默认值0,所以在A的static的构造函数执行完后,X的值变为1,然后返回B继续完成初始化,得到Y的值为2。最后执行Main,输出A.X和B.Y的值。相反地,如果将B中的Main方法移出放在一个类C中,那执行结果又是什么呢?依据以上的规则,可以很方便的得出答案。

    以下这题可以用来说明规则六,有兴趣的朋友可以思考一下答案
     class Class1
        {
            private static Class1 obj = new Class1();
            public static int counter1;
            public static int counter2 = 0;
            private Class1()
            {
                counter1++;
                counter2++;
            }
            public static Class1 getInstance()
            {
                return obj;
            }
           
            [STAThread]
            static void Main(string[] args)
            {
                Class1 obj = Class1.getInstance();
                Console.WriteLine("Class1.counter1=="+Class1.counter1);
                Console.WriteLine("Class1.counter2=="+Class1.counter2);
               
            }
        }

  • 相关阅读:
    理解SQL查询的底层原理
    Android手机里的垃圾文件和文件夹清理
    从树莓派开始玩电脑
    Oracle 游标使用全解
    oracle获得当前时间,精确到毫秒并指定精确位数
    Oracle存储过程创建及调用
    windows命令行(DOS批处理)添加任务计划
    JS计算字符串的长度
    皮肤和DLL和图片等项目文件完全整合到exe中
    C#中使用Socket实现简单Web服务器
  • 原文地址:https://www.cnblogs.com/zbo/p/1592712.html
Copyright © 2020-2023  润新知