C# 实例化的执行顺序

首先进行细分
1.类的成员分为:字段,属性,方法,构造函数

2.成员修饰符:静态成员,实例成员

不考虑继承的关系执行顺序为
1.静态字段
2.静态构造方法
3.实例字段
4.实例构造方法
其中 属性和方法只有在调用的时候才执行。
下面是一段代码例子

定义了一个类,当我们实例化的时候
Test test = new Test();
通过VS2008仿真 执行过程是
0. 静态的最先执行,仿真编译略过
1. F11 执行 public int mNum2=2; //简单的初始化字段
2. private int mNum3 = 3;
private int mNum4 = 4;
3. public Test() { temp = 1;mNum = 0; } //构造函数

以上是执行的顺序:
    与上面描述的的执行过程稳和,属性和字段跳过。public int mNum;也执行了,只不过系统默认赋值为空(null)或者0,系统西东除了的仿真时候跳过。
      class Test
        {
            public static int temp;

            public int mNum;
            public int mNum2=2;
            public void look()
            {
                Console.WriteLine("看我,我是test");
                Console.WriteLine("mNum={0}", mNum);
            }
            private int mNum3 = 3;
            private int mNum4 = 4;
            public int Num3
            {
                get { return mNum3; }
                set { mNum3= value; }
            }
          public  Test()
            {
                temp = 1;
                mNum = 0;
            }

        }

当存在继承关系的时候,执行的顺序。
1. 子类的静态字段
2. 子类的静态构造方法
3. 子类的实例字段
4. 父类的静态字段
5. 父类的静态构造方法
6. 父类的实例字段
7. 父类的实例构造方法
8. 子类的实例构造方法
下面是例子

1.  首先执行 class A中 int x = 1;,执行所有已经初始化后的字段,当执行到构造函数首执行父类字段
2.    int sd = 6;
3.    public A(),首先会去执行父类。
4.    0.    静态的最先执行,仿真编译略过
        1.    F11 执行 public int mNum2=2; //简单的初始化字段
        2.    private int mNum3 = 3;
               private int mNum4 = 4;
        3.    public  Test()  { temp = 1;mNum = 0; }   //构造函数
5.    public A()
        {
            PrintFields();
            look();
        }// 执行子类中自己的构造函数
6.     public virtual void PrintFields() ;执行自己类中有意义的虚函数
7.   执行调用父类的函数 look();
8.   接下来就将要执行 class B 中的内容了。过程类似,先一步一步的执行A类,在执行Test类,实现继承。
9.  忽略部分细节,降调B类中的细节。
         int z=2;
        public B() 运行到这里的时候,再次执行到  
        public A()
        {
            PrintFields();
            look();
        }
        的构造函数的时候,由于执行的是实例化B类,又在B类中重写了PrintFields();,实现多态。所以执行  public override void PrintFields()
        {
            Console.WriteLine("x={0},y={1}", "b", z);

        }
        所以此时的 z=2;
        而不是   public B()
        {
            z = -1;
        }
        中的z=-1,因为还没有执行到它,随后才执行子类中的构造函数。

10. 接下来是执行C类的实例化,C类中没有写C的构造函数,但是还是执行到了
B类(它的父类)中int z=2;,是因为,默认给写了无参的C类构造函数。
相当与 public C(){}
11. 所以任然能够继承,执行 public override void PrintFields()
{
Console.WriteLine(“j={0},k={1}”, “CC”, y);
}

 class A :Test
        {
            int x = 1;
            public A()
            {
                PrintFields();
                look();
            }
             int c;
            int sd = 6;
            public virtual void PrintFields() 
            {
                Console.WriteLine("j={0},k={1}", "AA", "AA");
            }
        }

        class B : A
        {

            int y;
            int z=2;
            public B()
            {
                z = -1;
            }

            public override void PrintFields()
            {
                Console.WriteLine("x={0},y={1}", "b", z);
            }
        }
        class C : B
        {
            int x = 1;
            int y = 3;
            public override void PrintFields()
            {
                Console.WriteLine("j={0},k={1}", "CC", y);
            }
        }
  static void Main(string[] args)
        {
            Test test = new Test();
            A a = new A();

            B b = new B();
            C c = new C();
            Console.ReadKey();
        }

补充说明

  1. 并不是每次实例化都是上面的顺序。因为静态的成员只是在第一次实例化的时候执行,以后再实例化都不会在执行。静态的成员意味着大家共享,且只有这一个。第一次实例化得到静态成员后,以后大家都共享,再次实例化,没有必要也不允许执行静态成员的部分。
  2. 在类中如果不添加访问修饰符,默认是静态的
  3. 非静态的字段,属性,方法,不能够作为右值。
  4. 构造引用类型的对象时,调用实例构造方法之前,为对象分配的内存总是先被归零,构造器没有显式重写字段,字段的值为0或者null,例如class Test 中的
    public int mNum;mNum 默认为0
  5. C#编译器提供了简化语法,允许在变量定义的时候就进行初始化(C++应该不行,在构 造函数汇总)但是存在了代码膨胀的问题。多个字段在定义时初始化,同时存在多个构造方法,每个构造方法都会把这些字段初始化的代码搬到自己的内部,这样造成代码的膨胀。
  6. 为了避免这样情况,可以把这些字段的初始化放到一个无参构造方法内,其他的构造方法显式调用无参构造方法。
  7. 初始化字段的两种方法
    ①使用简化语法:在定义的时候初始化
    ② 在构造方法内初始化。

效果图
这里写图片描述

  • 0
    点赞
  • 10
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值