zoukankan      html  css  js  c++  java
  • 避免在构造函数中调用虚方法(Do not call overridable methods in constructors)

    CLR中说道,不要在构造函数中调用虚方法,原因是假如被实例化的类型重写了虚方法,就会执行派生类型对虚方法的实现。但在这个时候,尚未完成对继承层次结构中所有字段的初始化。所以,调用虚方法会导致不可预测的行为。归根结底,这是由于调虚方法时,直到运行时之前,都不会选择执行该方法的实际类型。

    在MSDN中,也给我我们详细的提示和范例。

    https://msdn.microsoft.com/en-us/library/ms182331.aspx

    那我们就亲手来测试一下,新建两个类,Perople类,Chinese类,先不要看结果,看到下面这两个类,想想在实例化Chinese的时候,会是什么输出结果呢?

     1  public class People
     2     {
     3         public People()
     4         {
     5             PeopleSayHello();
     6         }
     7 
     8         public virtual void PeopleSayHello()
     9         {
    10             Console.WriteLine("hello");
    11         }
    12     }
    public class Chinese : People
        {
            private bool HaveAbility { get; set; }
    
            public Chinese()
            {
                HaveAbility = true;
            }
    
            public override void PeopleSayHello()
            {
                
                Console.WriteLine((HaveAbility?"":"没有")+"能力说你好");
            }
        }

    接下来来看调用和输出结果吧:

    是不是和你在脑海里运行的结果相同?

    其实原因在第一句话中已经说的比较清晰了,更通俗的说就是在派生类实例化的时候,如果没有显式调用基的任意一个构造函数,那么默认选择基类的无参构造。所以在本例中,实例化Chinese的时候,首先执行了基类的无参构造。

    和实例构造器初始化的顺序也相关,在创建实例的时候,首先为数据字段分配内存,然后初始化对象附加字段,包括类型对象的指针引用,最后才调用类型的构造函数设置对象的初始状态。

     

  • 相关阅读:
    时间比较
    syslog 协议及其在 SysLogHandler 中的使用
    获取 postgresql 的当前索引
    dns域名解析
    wireshark
    ctypes使用
    python模块signal
    ThreadPoolExecutor多线程异步执行
    异步进程 multiprocessing 模板
    redis常见错误
  • 原文地址:https://www.cnblogs.com/tdws/p/6885380.html
Copyright © 2011-2022 走看看