建议95:避免在构造方法中调用虚成员
2016-09-09 09:59
218 查看
建议95:避免在构造方法中调用虚成员
在构造方法中调用虚方法会带来一些意想不到的错误,虽然这种方法不常见,但还是需要注意这类陷阱。
运行会出现异常NullReferenceException:未将对象引用设置到对象的实例。
在调用者代码中,我们需要创建一个American的实例对象american。由于发现实例还存在一个积累Person,所以运行时会首先调用基类的构造方法。在构造方法中Person调用了虚方法InitSkin。由于是虚方法,所以会在运行时调用子类的InitSkin方法。子类的InitSkin方法中,需要打印出名字。而这个时候,方法的调用堆栈还一直在基类的构造方法内,也就是在子类的构造方法中的代码还完全没有执行:
所以会抛出异常。
基于以上原因,建议不要在构造方法中调用虚成员。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
在构造方法中调用虚方法会带来一些意想不到的错误,虽然这种方法不常见,但还是需要注意这类陷阱。
static void Main() { American american = new American(); Console.ReadKey(); } class Person { public Person() { InitSkin(); } protected virtual void InitSkin() { //省略 } } class American : Person { Race Race; public American() : base() { Race = new Race() { Name = "White" }; } protected override void InitSkin() { Console.WriteLine(Race.Name); } } class Race { public string Name { get; set; } }
运行会出现异常NullReferenceException:未将对象引用设置到对象的实例。
在调用者代码中,我们需要创建一个American的实例对象american。由于发现实例还存在一个积累Person,所以运行时会首先调用基类的构造方法。在构造方法中Person调用了虚方法InitSkin。由于是虚方法,所以会在运行时调用子类的InitSkin方法。子类的InitSkin方法中,需要打印出名字。而这个时候,方法的调用堆栈还一直在基类的构造方法内,也就是在子类的构造方法中的代码还完全没有执行:
Race = new Race() { Name = "White" };
所以会抛出异常。
基于以上原因,建议不要在构造方法中调用虚成员。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
相关文章推荐
- php构造方法中析构方法在继承中的表现
- PHP的构造方法,析构方法和this关键字详细介绍
- PHP类的声明与实例化及构造方法与析构方法详解
- Java中子类调用父类构造方法的问题分析
- java继承中的构造方法实例解析
- 深入解析Swift编程中的构造方法
- IOS之构造方法与自定义构造方法的区别与实现
- php构造方法中析构方法在继承中的表现
- 随笔 ——1
- 浅析java构造函数
- 黑马程序员——OC基础——构造方法
- 黑马程序员IOS-OC语言-构造方法
- Java基础(3)
- 黑马程序员——Objective-C语言知识整理——构造方法相关知识总结
- 黑马程序员-关键字及构造方法的使用
- OC中得构造方法
- 黑马程序员-@property,@synthesize关键字及构造方法笔记
- OC中一些重要知识点<二>
- Java中的构造方法
- 构造方法串起来