zoukankan      html  css  js  c++  java
  • 6 CLR实例构造器

    引用类型构造器

    如果我们没有定义实例构造器,那么编译器会为我们默认产生一个无参构造器。

    实例对象初始化过程

    • 为实例分配内存;
    • 初始化附加成员,包括方法表指针和SyncBlockIndex变量(我们已经在

      image

      image

      调用顺序

      如果类没有显示定义构造器,编译器会自动生成一个无参构造器,调用基类的无参构造器。例如

      public class Animal{}

      相当于

      public class Animal

      {

         public Animal():base(){}

      }

      如果类的修饰符为static(sealed和abstract),编译器不会默认生成构造器;

      如果基类没有提供无参构造器,那么派生类必须显示调用一个构造器,否则编译错误。

      如果存在继承关系,派生类在使用基类的字段之前应该先调用基类的构造器。如果派生类没有显式调用基类构造器,则编译器会自动产生调用基类无参构造器的代码,沿着继承层次一直到System.Object的无参构造器位置。例如下面,调用Dog dog=new Dog()方法的结果。

      image

      class Dog:Animal。。。

      image

      Dog()方法IL代码

      image

      代码爆炸?

      为了防止构造器重载时大量重复赋值造成代码膨胀,我们建议将公共的初始化语句放在一个构造函数中,然后其他的构造器显式调用该构造器。

     class A
            {
                public int xxxx = 100;
                public int xxxx2 = 100;
                public int xxxx3 = 100;
    
                public A()
                {
                    Console.WriteLine("我是类A的无参构造器");
                }
    
                public A(string ss)
                {
                    Console.WriteLine("我是类A的无参构造器");
                }
            }
    
            //编译后等价于
            class A
            {
                public int xxxx;
                public int xxxx2;
                public int xxxx3;
    
                public A()
                {
                    xxxx = 100;
                    xxxx2 = 100;
                    xxxx3 = 100;
                    Console.WriteLine("我是类A的无参构造器");
                }
    
                public A(string ss)
                {
                    xxxx = 100;
                    xxxx2 = 100;
                    xxxx3 = 100;
                    Console.WriteLine("我是类A的无参构造器");
                }
            }
    
    
            /// <summary>
            /// ////////////////////////////////////////////////////////////////////////////////////////////////
            /// </summary>
            class A
            {
                public int xxxx = 100;
                public int xxxx2 = 100;
                public int xxxx3 = 100;
    
                public A()
                {
                    Console.WriteLine("我是类A的无参构造器");
                }
    
                //防止代码爆炸
                public A(string ss):this()
                {
                    Console.WriteLine("我是类A的无参构造器");
                }
            }
    
            //编译后等价于
            class A
            {
                public int xxxx;
                public int xxxx2;
                public int xxxx3;
    
                public A()
                {
                    xxxx = 100;
                    xxxx2 = 100;
                    xxxx3 = 100;
                    Console.WriteLine("我是类A的无参构造器");
                }
    
                public A(string ss):this()
                {
                    Console.WriteLine("我是类A的无参构造器");
                }
            }

    值类型构造器

    • 值类型没有默认产生的无参构造器,也不允许我们定义无参构造器。但是我们可以自定义带参数的构造器。

    image

    • 不允许在值类型中内联实例字段的初始化。下面的例子会产生编译错误。
      struct TestStruct
          { 
             partial int number=5;
          }
    • 值类型带参构造函数必须对所有实例字段进行初始化才可以。如果有变量没有初始化,就会报错。

    image 

    如果不想对所有字段一一初始化,有一种替代方案:

    复制代码
      struct Dog
        {
            public int age;
            public string name;
            public Dog(string Name)
            {
                this = new Dog();
                name = Name;
            }
        }
    复制代码

    在值类型构造器中,this代表值类型本身的一个实例,用New创建的值类型实例赋给this时,会将所有字段置零。所以这个方案可以编译通过。

    • 带参构造函数定义之后需要用new显式调用才能执行。否则值类型的字段会保持0或Null值。

    image     image

  • 相关阅读:
    There is an overlap in the region chain修复
    There is an overlap in the region chain
    region xx not deployed on any region server
    python 中的re模块,正则表达式
    TCP粘包问题解析与解决
    yield from
    Git push提交时报错Permission denied(publickey)...Please make sure you have the correct access rights and the repository exists.
    mysql 中Varchar 与char的区别
    Mysql 字符集及排序规则
    请实现一个装饰器,限制该函数被调用的频率,如10秒一次
  • 原文地址:https://www.cnblogs.com/aaa6818162/p/4798213.html
Copyright © 2011-2022 走看看