CLR via C#第8章:实例构造器(引用类型)

  • 实例构造器不能被继承,也就是说不能用override,virtual,sealed,abstract,new来修饰
  • 如果没有显示的定义构造器,编译器会默认定义一个无参构造器,除非是静态类。
  • 创建一个引用类型的实例的过程如下:
  1. 为这个实例的数据字段分配内存(初始内存为0)
  2.  初始化对象的附加字段(类型对象指针和同步索引块)
  3. 调用类型的实例构造器初始化对象的初始状态。(在初始化字段之前所有的字段均为0或者null)
  •  在构造器中的字段初始化
     class Father
        {
            public Father()
            {
                MethodFather();
            }
            public virtual void MethodFather()
            {
                
                Console.WriteLine("FatherMethod");
            }
        }
        class Son : Father
        {
            int ss = 10;
            double dd = 2.3;
            public Son()
            {
                //dd = 12;
            }
            public Son(string s)
            {
                dd = 13;
            }
            public override void MethodFather()
            {
                Console.WriteLine("SonMethod");
            }
        }

    IL代码如下 :

       

这是无参构造器的IL代码,如上所示,在构造器中会先初始化两个字段值,然后再调用父类构造函数。

这是有参构造函数:

也是先初始化字段值,然后调用父类构造函数,不同的是,最后会执行自己定义的其他的代码(此处是覆盖dd的值) .

注意:每个构造函数都会初始化字段值和调用父类的无参构造函数。但是,对于某些初始化参数是一致的构造函数,如果在每个构造函数中初始化字段值,然后调用父类构造函数,这样其实是不合理的。其实。可以考虑创建单个的构造器来执行这些公共的初始化,然后,让其他构造器显示调用这个公共初始化构造器,这样可以减少生成的代码。

如下是改进的Son类代码:

    class Son : Father
    {
        int ss = 10;
        double dd = 2.3;
        public Son()
        {
            //dd = 12;
        }
        public Son(string s):this()
        {
            dd = 13;
        }
        public override void MethodFather()
        {
            Console.WriteLine("SonMethod");
        }
    }

 生成的IL代码如下:

 无参构造函数的不变的。

有参构造函数分析如下:

此时,有参构造中的字段初始化和父类无参构造的调用没有了(之前的前两步).只是多了一个无参构造的调用,然后,跟之前的一样,执行有参构造中自己的代码(初始化dd字段)

猜你喜欢

转载自blog.csdn.net/maoxiaohai123/article/details/84766237
今日推荐