Virtual member call in a constructor

后端 未结 18 2127
[愿得一人]
[愿得一人] 2020-11-22 01:27

I\'m getting a warning from ReSharper about a call to a virtual member from my objects constructor.

Why would this be something not to do?

18条回答
  •  一整个雨季
    2020-11-22 02:02

    One important missing bit is, what is the correct way to resolve this issue?

    As Greg explained, the root problem here is that a base class constructor would invoke the virtual member before the derived class has been constructed.

    The following code, taken from MSDN's constructor design guidelines, demonstrates this issue.

    public class BadBaseClass
    {
        protected string state;
    
        public BadBaseClass()
        {
            this.state = "BadBaseClass";
            this.DisplayState();
        }
    
        public virtual void DisplayState()
        {
        }
    }
    
    public class DerivedFromBad : BadBaseClass
    {
        public DerivedFromBad()
        {
            this.state = "DerivedFromBad";
        }
    
        public override void DisplayState()
        {   
            Console.WriteLine(this.state);
        }
    }
    

    When a new instance of DerivedFromBad is created, the base class constructor calls to DisplayState and shows BadBaseClass because the field has not yet been update by the derived constructor.

    public class Tester
    {
        public static void Main()
        {
            var bad = new DerivedFromBad();
        }
    }
    

    An improved implementation removes the virtual method from the base class constructor, and uses an Initialize method. Creating a new instance of DerivedFromBetter displays the expected "DerivedFromBetter"

    public class BetterBaseClass
    {
        protected string state;
    
        public BetterBaseClass()
        {
            this.state = "BetterBaseClass";
            this.Initialize();
        }
    
        public void Initialize()
        {
            this.DisplayState();
        }
    
        public virtual void DisplayState()
        {
        }
    }
    
    public class DerivedFromBetter : BetterBaseClass
    {
        public DerivedFromBetter()
        {
            this.state = "DerivedFromBetter";
        }
    
        public override void DisplayState()
        {
            Console.WriteLine(this.state);
        }
    }
    

提交回复
热议问题