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 discoveredSayIf there is an overload, The subclass is called.ChineseMediumSayBut the subclassChineseNoAgeAttribute initialization.AgeThe 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.