• 总结:CLR Via C#(第八章):构造器


    实例构造器和类(引用类型):

    1、 类只能拥有类自己的实例构造器;实例构造器不能被继承;

    2、 以下修饰符不能用于实例构造器:virtualnewoverridesealedabstract

    如果类的修饰符为abstract,那么默认构造器可访问性为protected,否则为public

    3、 如果基类没有提供无参构造器,那么类必须显示调用基类的构造器,否则编译出错;

       public abstract class Base2

        {

            public Base2(int i)

            {

                Console.WriteLine("Base2:" + i);

            }

        }

        //ErrorBase2方法没有采用“”个参数的重载

        //public class Child2 : Base2

        //{

        //}

        public class Child2: Base2      

        {

             public Child2(int i):base(i)

            {

                Console.WriteLine("Child2:" + i);

            }

        }

    如果类的修饰符为staticsealedabstract),那么编译器不会在类的定义中生成一个默认的构造器;

    4、 类的实例构造器在访问基类继承的任何字段之前,必须调用其基类的构造器;

    5、 在构造器中不能调用任何虚方法(虽然编译无错),这样会影响所创建的对象,导致无法预测;

        public abstract class Base2

        {

            public Base2()

            {

                Virtual_Fn();

            }

            public virtual void Virtual_Fn()

            {

                Console.WriteLine("Base2:Virtual_Fn");

            }

        }

        public class Child2 : Base2

        {

            public Child2()

            {

                Virtual_Fn();

            }

            public override void Virtual_Fn()

            {

                Console.WriteLine("Child2:Virtual_Fn");

            }

        }

     

    输出:

    Child2:Virtual_Fn

    Child2:Virtual_Fn

     

    6、 下面的代码中,类有三个构造器,所以编译器产生三次初始化m_xm_sm_d——每次构造器一次;

         internal sealed class SomeType {

             private Int32 m_x = 5;

             private String m_s = "Hi there";

             private Double m_d = 3.14159;

             private Byte   m_b;

     

             // Here are some constructors.

             public SomeType()         { /* ... */ }

             public SomeType(Int32 x) { /* ... */ }

             public SomeType(String s) { /* ...; */ m_d = 10; }

         }

    可以将公共初始化语句放到一个单独的初始化构造器中,以减少生成的代码大小;

    改造如下:

    internal sealed class SomeType

        {

            // Do not explicitly initialize the fields here

            private Int32 m_x;

            private String m_s;

            private Double m_d;

            private Byte m_b;

     

            // This method MUST be called by all constructors.

            public SomeType()

            {

                m_x = 5;

                m_s = "Hi there";

                m_d = 3.14159;

                m_b = 0xff;

            }

     

            // This constructor sets all fields to their default, then changes m_x.

            public SomeType(Int32 x) : this()

            {

                m_x = x;

            }

     

            // This constructor sets all fields to their default, then changes m_s.

            public SomeType(String s) : this()

            {

                m_s = s;

            }

        }

     

    实例构造器和结构(值类型):

    1、 CLR允许创建值类型的实例,但是无法阻止值类型的初始化,因此值类型实际上不需要在其内部定义构造器;

    值类型的构造器只有在被显式调用时才会执行;

    C#不允许值类型显式定义无参构造器;

        //Error:结构不能包含显式的无参数构造函数

        //public struct Point

        //{

        //    public Point()

        //    {

        //    }

    //}

    2、 值类型的构造器必须初始化值类型的所有字段;

        public struct Point

        {

            private int m_x;

            private int m_y;

     

            // Error:必须给所有字段初始化

            public Point(int x)

            {

                m_x = x;

                // m_y没有被初始化

            }

        }

    类型构造器(静态构造器):

    1、 类型构造器可以用于接口、引用类型、值类型;

    2、 一般不在类型内部定义类型构造器,如果定义,不能超过一个;

    3、 C#自动将类型构造器标记为private,类型构造器前不能有访问修饰符;

        public class Base1

        {

            // Error静态构造器必须无参

            static Base1(int i)

            {

            }

     

            // Error类型构造器不允许出现访问修饰符

            private static Base1()

            {

            }

     

        }

    4、 永远不要在值类型中定义类型构造器,虽然可以这样做,因为CLR中存在不调用值类型的静态构造器的情况;

       internal struct SomeValueType

        {

            public int m_x;

            static SomeValueType()

            {

                Console.WriteLine("Static 构造器");

            }

    }

            static void Main(string[] args)

            {

                SomeValueType some = new SomeValueType();

                Console.WriteLine(some.m_x);

                Console.ReadLine();

         }

             输出:0

             静态构造器没有执行;

    5、使用静态构造器时,要注意多线程同步;

     

  • 相关阅读:
    如何更改AD域安全策略-密码必须符合复杂性要求
    Flameshot:一个简洁但功能丰富的截图工具
    Linux桌面最轻量的Dock之Plank介绍
    NVIDIA vGPU License服务器搭建详解
    阿姜查 | 当一个人不了解死亡时,生活会非常烦恼
    阿姜查:工作永远没完没了 你为何着急做完?
    .NET 通用高扩展性的细粒度权限管理架构(webApi/Mvc)
    WebApi实现通讯加密 (转)
    MVC
    程序员的沟通之痛
  • 原文地址:https://www.cnblogs.com/LeimOO/p/1654304.html
Copyright © 2020-2023  润新知