首页 > 代码库 > 在基类构造器中调用虚方法需谨慎
在基类构造器中调用虚方法需谨慎
最近,在基类的构造函数中调用虚方法时,发现了一个问题。先把问题重现如下:
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));}}
总结:当在基类构造函数中调用虚方法需谨慎,因为当父类调用虚方法重载的时候,子类还没有被初始化,可能会涉及到一些成员还未被初始化。
在基类构造器中调用虚方法需谨慎
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。