博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
在基类构造器中调用虚方法需谨慎
阅读量:6682 次
发布时间:2019-06-25

本文共 1203 字,大约阅读时间需要 4 分钟。

最近,在基类的构造函数中调用虚方法时,发现了一个问题。先把问题重现如下:

 
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有重载,就调用子类ChineseSay的重载,但此时子类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));
}
}
 
 

 

 

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

转载地址:http://rmxao.baihongyu.com/

你可能感兴趣的文章
回顾2014,展望2015
查看>>
BIOS基础知识(下)
查看>>
nmom结果记录
查看>>
Iterator 和 Iterable 区别和联系
查看>>
经典SQL语句大全
查看>>
测试LCD1602的显示,显示时间,提示语
查看>>
Linux常用命令
查看>>
Windows系统一键备份还原工具,支持UEFI和Legacy模式
查看>>
MySQL对分隔符的处理(二)
查看>>
centos 6.3 源码安装mysql
查看>>
SecureCRT 连接Ubuntu乱码解决
查看>>
Zabbix
查看>>
Linux运维学习历程-第十二天-bash脚本与程序包管理
查看>>
Restorator V2009 单文件版
查看>>
Zabbix man手册
查看>>
APUE读书笔记-09进程关系(02)
查看>>
来南京工作两个月了!
查看>>
EDM邮件营销的七个基本原则
查看>>
dropna(thresh=n) 的用法
查看>>
谨慎Asp.net中static变量的用法
查看>>