当在一个非sealed类的构造函数中调用一个 virtual 方法的时候,vs会提示一个virtual member call in constructor的警告,如图:
既然是警告那就说明此处可能会有坑,细究一下。
首先需要知道:
1、c#中对象的初始化顺序是从最外层派生类开始,直至最顶层基类;
2、构造函数的执行顺序刚好相反,从顶层基类开始,直至最外层派生类。
基于以上两点认识,那么就可以明白,在基类的构造函数中调用一个 virtual 方法的时候,一定是调用的派生类重写的那个方法,换句话说,也就是在调用派生类重写的方法的时候,派生类的构造函数还没有执行。
这样会有什么问题呢,看下示例代码:
1
public
class Father
2 {
3 public string LastName { get; set; }
4
5 public Father()
6 {
7 LastName = " Zhang ";
8
9 ShowFullname();
10 }
11
12 public virtual void ShowFullname()
13 {
14 Console.WriteLine(LastName);
15 }
16 }
17
18 public class Son : Father
19 {
20 public string FirstName { get; set; }
21
22 public Son( string firstName)
23 {
24 FirstName = firstName;
25 }
26
27 public override void ShowFullname()
28 {
29 Console.WriteLine( " Fullname: {0} {1} ", FirstName, LastName);
30 }
31 }
2 {
3 public string LastName { get; set; }
4
5 public Father()
6 {
7 LastName = " Zhang ";
8
9 ShowFullname();
10 }
11
12 public virtual void ShowFullname()
13 {
14 Console.WriteLine(LastName);
15 }
16 }
17
18 public class Son : Father
19 {
20 public string FirstName { get; set; }
21
22 public Son( string firstName)
23 {
24 FirstName = firstName;
25 }
26
27 public override void ShowFullname()
28 {
29 Console.WriteLine( " Fullname: {0} {1} ", FirstName, LastName);
30 }
31 }
运行一下:
一目了然,还没给儿子起名字就要写户口了。