本文将介绍以下内容:
1. 引言
new关键字引起了大家的不少关注,尤其感谢Anders Liu的补充,让我感觉博客园赋予的交流平台真的无所不在。所以,我们就有必要继续这个话题,把我认为最值得关注的关键字开展下去,本文的重点是访问关键字(Access Keywords):base和this。虽然访问关键字不是很难理解的话题,我们还是有可以深入讨论的地方来理清思路。还是老办法,我的问题先列出来,您是否做好了准备。
2. 基本概念
base和this在C#中被归于访问关键字,顾名思义,就是用于实现继承机制的访问操作,来满足对对象成员的访问,从而为多态机制提供更加灵活的处理方式。
2.1 base关键字
其用于在派生类中实现对基类公有或者受保护成员的访问,但是只局限在构造函数、实例方法和实例属性访问器中,MSDN中小结的具体功能包括:
2.2 this关键字
其用于引用类的当前实例,也包括继承而来的方法,通常可以隐藏this,MSDN中的小结功能主要包括:
3. 深入浅出
3.1 示例为上
下面以一个小示例来综合的说明,base和this在访问操作中的应用,从而对其有个概要了解,更详细的规则和深入我们接着阐述。本示例没有完全的设计概念,主要用来阐述base和this关键字的使用要点和难点阐述,具体的如下:
3.2 示例说明
上面的示例基本包括了base和this使用的所有基本功能演示,具体的说明可以从注释中得到解释,下面的说明是对注释的进一步阐述和补充,来说明在应用方面的几个要点:
.method public hidebysig virtual instance void ShowResult() cil managed { // 代码大小 27 (0x1b) .maxstack 8 IL_0000: nop IL_0001: ldarg.0 //base调用父类成员 IL_0002: call instance void Anytao.net.My_Must_net.Car::ShowResult() IL_0007: nop IL_0008: ldarg.0 //base调用父类成员,因为没有实现Car.Run(),所以指向更高级父类 IL_0009: call instance void Anytao.net.My_Must_net.Vehicle::Run() IL_000e: nop IL_000f: ldstr "It's audi's result." IL_0014: call void [mscorlib]System.Console::WriteLine(string) IL_0019: nop IL_001a: ret } // end of method Audi::ShowResult
3.3 深入剖析
如果有三次或者更多继承,那么最下级派生类的base指向那一层呢?例如.NET体系中,如果以base访问,则应该是直接父类实例呢,还是最高层类实例呢?
首先我们有必要了解类创建过程中的实例化顺序,才能进一步了解base机制的详细执行过程。一般来说,实例化过程首先要先实例化其基类,并且依此类推,一直到实例化System.Object为止。因此,类实例化,总是从调用System.Object.Object()开始。因此示例中的类Audi的实例化过程大概可以小结为以下顺序执行,详细可以参考示例代码分析。
我们在充分了解其实例化顺序的基础上就可以顺利的把握base和this在作用于构造函数时的执行情况,并进一步了解其基本功能细节。
下面更重要的分析则是,以ILDASM.exe工具为基础来分析IL反编译代码,以便更深层次的了解执行在base和this背后的应用实质,只有这样我们才能说对技术有了基本的剖析。
Main方法的执行情况为:
因此,对重写父类方法,最终指向了最高级父类的方法成员。
4. 通用规则
5. 结论
base和this关键字,不是特别难于理解的内容,本文之所以将其作为系列的主题,除了对其应用规则做以小结之外,更重要的是在关注其执行细节的基础上,对语言背景建立更清晰的把握和分析,这些才是学习和技术应用的根本所在,也是.NET技术框架中本质诉求。对学习者来说,只有从本质上来把握概念,才能在变化非凡的应用中,一眼找到答案。