构造函数调用虚函数的进一步探讨

在blog上看到一篇文章《 FxCop 的 ConstructorsShouldNotCallBaseClassVirtualMethods 规范 》原文: http://blog.csdn.net/xamcsdn2/archive/2004/08/11/71766.aspx

颇感兴趣,写了一段代码研究(估计还称不上研究,就当探索吧)了一下。

代码如下。

using System;

namespace test_console
{

??? class baseclass
??? {
??????? public int count = 0 ;
??????? public baseclass()
??????? {
??????????? Console.WriteLine( " Call BaseClass's Constructor Function... " );
??????????? Increase( " base " );
??????? }

??????? public virtual void Increase( string type)
??????? {
??????????? Console.WriteLine(type);
??????????? Console.WriteLine( " Call BaseClass's Increase Function... " );
??????????? count ++ ;
??????? }
??? }

??? class subclass:baseclass
??? {
??????? public int subcount = 0 ;

??????? public subclass()
??????? {
??????????? Console.WriteLine( " Call SubClass's Constructor Function... " );
??????????? Console.WriteLine(subcount.ToString());
??????????? Increase( " sub " );
??????? }

??????? public override void Increase( string type)
??????? {
??????????? Console.WriteLine(type);
??????????? Console.WriteLine( " Call SubClass's Increase Function... " );
??????????? subcount ++ ;
??????????? Console.WriteLine(subcount.ToString());
??????? }
??????? ///
??????? /// 应用程序的主入口点。
??????? ///
??????? [STAThread]
??????? static void Main( string [] args)
??????? {
??????????? subclass c = new subclass();
??????????? Console.ReadLine();
??????? }
??? }
}

baseclass的构造函数调用了Increase()函数,subclass的构造函数同样调用了此函数。运行结果如下:

Call BaseClass's Constructor Function...
base
Call SubClass's Increase Function...
1
Call SubClass's Constructor Function...
1
sub
Call SubClass's Increase Function...
2

可以看到SubClass的Increase函数被调用了两次,我在subclass的increase中加入一个参数来判断是由哪个构造函数来调用的,结果是先由baseclass调用,再由subclass调用。而且看上去似乎baseclass是先于subclass调用的,但是事实究竟如何呢?我们来看一下subclass的构造函数的IL代码:

.method public hidebysig specialname rtspecialname instance void .ctor() cil managed
{
????? // Code Size: 51 byte(s)
????? .maxstack 2
????? L_0000: ldarg. 0
????? L_0001: ldc.i4. 0
????? L_0002: stfld int32 test_console.subclass::subcount
????? L_0007: ldarg. 0
????? L_0008: call instance void test_console.baseclass::.ctor()
????? L_000d: ldstr " Call SubClass's Constructor Function... "
????? L_0012: call void [mscorlib]System.Console::WriteLine( string )
????? L_0017: ldarg. 0
????? L_0018: ldflda int32 test_console.subclass::subcount
????? L_001d: call instance string int32::ToString()
????? L_0022: call void [mscorlib]System.Console::WriteLine( string )
????? L_0027: ldarg. 0
????? L_0028: ldstr " sub "
????? L_002d: callvirt instance void test_console.baseclass::Increase( string )
????? L_0032: ret
}
一目了然,L_0008: call instance void test_console.baseclass::.ctor()在subclass的构造函数中先调用了baseclass的构造函数。

?

后记:作为面对对象程序设计者的基本知识,在这里谈论子类构造函数先调用父类构造函数这一点似乎有点画蛇添足,作为小弟的第一篇作品,希望能给那些初学者一些帮助吧。

Published At
Categories with Web编程
Tagged with
comments powered by Disqus