Be cautious when calling Virtual Methods in the base class constructor.
Recently, a problem was found when calling a virtual method in the base class constructor. First, reproduce the problem as follows:
class Program
{
static void Main(string[] args)
{
var c = new Chinese(18);
Console.ReadKey();
}
}
public class People
{
public int Age { get; protected set; }
protected People()
{
this.Say();
}
public virtual void Say()
{
Console. WriteLine (string. Format ("the base class says I am {0} years old", Age ));
}
}
public class Chinese : People
{
public Chinese(int age)
{
this.Age = age;
}
public override void Say()
{
Console. WriteLine (string. Format ("subclass says I am {0} years old", Age ));
}
}
If you run the above Code, will the result be one of the following two situations?
Base Class: I'm 18 years old.
Subclass: I am 18 years old.
None! But:
Why?
→ Call subclass Constructornew Chinese(18)
→ Call the non-argument constructor of the parent class and call the virtual MethodSay
→ Virtual Methods discoveredSay
If there is an overload, The subclass is called.Chinese
MediumSay
But the subclassChinese
NoAge
Attribute initialization.Age
The default value is 0.
How can we avoid it?
-- Remove the code that calls the virtual method in the base class constructor.
-- Use a subclass instance to call the overload method
class Program
{
static void Main(string[] args)
{
var c = new Chinese(18);
c.Say();
Console.ReadKey();
}
}
public class People
{
public int Age { get; protected set; }
protected People()
{
}
public virtual void Say()
{
Console. WriteLine (string. Format ("the base class says I am {0} years old", Age ));
}
}
public class Chinese : People
{
public Chinese(int age)
{
this.Age = age;
}
public override void Say()
{
Console. WriteLine (string. Format ("subclass says I am {0} years old", Age ));
}
}
Conclusion: Be cautious when calling Virtual Methods in the base class constructor, because when the parent class calls a virtual method overload, The subclass has not been initialized, some members may not be initialized yet.