C在C#中,用virtual关键字修饰的方法(属性、事件)称为虚方法(属性、事件),在C#中如果存在类的继承关系,应避免在构造函数中调用虚成员。下面通过一个实例说明为什么不建议在C#中的构造函数中调用虚方法或虚属性的原因

C

Visual Studio 中安装了Resharper插件时,如果在构造函数中调用虚方法或虚属性时,编辑器会出现如下警告:

下面通过一个实例说明

 1、实例代码

  •  
  • C# 代码   复制
  • 
    using System;
    
    namespace VirtualDemo
    {
        class Program
        {
            static void Main(string[] args)
            {
                var test = new SubClass();
                Console.ReadKey();
            }
        }
    
        class BaseClass
        {
            protected virtual string VirtualProperty { get; set; }
    
            public BaseClass()
            {
                var p = VirtualProperty;
                VirtualMethod();
            }
    
            protected virtual void VirtualMethod()
            {
    
            }
        }
    
        class SubClass : BaseClass
        {
            private MockClass _mockClass;
    
            public SubClass()
            {
                _mockClass = new MockClass();
            }
    
            protected override string VirtualProperty
            {
                get { return _mockClass.MockProperty; }
                set { _mockClass.MockProperty = value; }
            }
    
            protected override void VirtualMethod()
            {
                var p = _mockClass.MockProperty;
            }
        }
    
        class MockClass
        {
            public string MockProperty { get; set; }
        }
    }
    
    		
  • 2、运行时, 在构造SubClass时会报空引用的错误。

    3、报错原因

    因为基类构造函数先于子类构造函数运行,而子类构造函数中初始化了一个成员类,但是基类构造函数访问虚成员时子类还没构造,所以出现了空引用报错。