您的位置:首页 > 其它

在基类构造器中调用虚方法需谨慎

2014-11-21 09:39 239 查看
最近,在基类的构造函数中调用虚方法时,发现了一个问题。先把问题重现如下:

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("基类说我今年{0}岁了", Age));
}
}
public class Chinese : People
{
public Chinese(int age)
    {
this.Age = age;
}
public override void Say()
    {
Console.WriteLine(string.Format("子类说我今年{0}岁了",Age));
}
}


运行以上的代码,结果会是以下两种情况之一吗?
基类说我今年18岁了
子类说我今年18岁了

都不是!而是:




为什么?
→调用子类构造函数
new Chinese(18)

→先调用父类无参构造函数,并调用虚方法
Say

→发现虚方法
Say
有重载,就调用子类
Chinese
Say
的重载,但此时子类
Chinese
还没有对
Age
属性初始化,此时的
Age
属性值为默认值0

如何避免呢?
--去掉在基类构造函数中调用虚方法的代码
--用子类实例调用重载方法

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("基类说我今年{0}岁了", Age));
}
}
public class Chinese : People
{
public Chinese(int age)
    {
this.Age = age;
}
public override void Say()
    {
Console.WriteLine(string.Format("子类说我今年{0}岁了",Age));
}
}








总结:当在基类构造函数中调用虚方法需谨慎,因为当父类调用虚方法重载的时候,子类还没有被初始化,可能会涉及到一些成员还未被初始化。

内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: