base想到...

简介:

base 是C#中77个(如果没有记错的话tongue_smile.gif)关键字之一,在MSDN文档中列举的主要作用是两个:
1. 调用基类上已被其他方法重写的方法。
2. 指定创建派生类实例时应调用的基类构造函数。

注意点:基类访问只能在构造函数、实例方法或实例属性访问器中进行,从静态方法中使用base关键字是错误的。


对于第1点,作用十分明显,重写了父类函数,但是又需要调用父类函数的时候就需要用到了,例如下面的代码:

None.gif using System;
None.gif
None.gif class BaseClass
ExpandedBlockStart.gif {
InBlock.gif    public BaseClass()
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("[BaseClass.BaseClass] " + 
InBlock.gif           "Constructor called");           
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public BaseClass(int foo)
ExpandedSubBlockStart.gif    {
InBlock.gif            Console.WriteLine("[BaseClass.BassClass] " +
InBlock.gif               " Argument parameter is {0}", foo.ToString());    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public virtual void PrintInfo()
ExpandedSubBlockStart.gif    {
InBlock.gif            Console.WriteLine("[BaseClass.BaseClass] " + 
InBlock.gif                " PrintInfo method Invoked! ");    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
ExpandedBlockEnd.gif}

None.gif
None.gif class DerivedClass : BaseClass
ExpandedBlockStart.gif {
InBlock.gif    public DerivedClass() : base(100)
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("Thisdot.gif");    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public DerivedClass(int foo) : this()
ExpandedSubBlockStart.gif    {        
InBlock.gif        Console.WriteLine("[DerivedClass.Derived] " +
InBlock.gif             "Constructor called");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public override void PrintInfo()
InBlock.gif//        public void PrintInfo()
ExpandedSubBlockStart.gif
    {
InBlock.gif//        base.PrintInfo();
InBlock.gif
            Console.WriteLine("[DerivedClass.Derived] " +
InBlock.gif                 " PrintInfo method Invoked!!!");    
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif class DefaultInitializer
ExpandedBlockStart.gif {
InBlock.gif    public static void Main()
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("[Main] Instantiating a " +
InBlock.gif           "DerivedClass object");
InBlock.gif        DerivedClass derived = new DerivedClass(100);
InBlock.gif        derived.PrintInfo();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
        
None.gif

结果和作用都是大家预期的。

用ildasm来看一下,这个过程在IL代码中是如何进行的?
base1.JPG
调用override的函数,是指回去父类中去的,但是调用的代码效果却又不是父类中的代码,呵呵~~

而在没有override时候呢, 则是这样的:
base2.JPG

重写后的函数调用父类在增加了base.PrintInfo();后在IL可以看到,其实它是直接调用父类中函数的:
增加了base.PrintInfo();后:
base3.JPG

没有增加:
base4.JPG

可见重写函数中是直接调用父类对应函数的。

两层类结构的IL代码如此,那么三层呢?IL出现的是最上层的类调用还是父类调用呢?
用下面的代码:

None.gif using System;
None.gif
None.gif class BaseClass
ExpandedBlockStart.gif {
InBlock.gif    public BaseClass()
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("[BaseClass.BaseClass] " + 
InBlock.gif           "Constructor called");           
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public BaseClass(int foo)
ExpandedSubBlockStart.gif    {
InBlock.gif            Console.WriteLine("[BaseClass.BassClass] " +
InBlock.gif               " Argument parameter is {0}", foo.ToString());    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public virtual void PrintInfo()
ExpandedSubBlockStart.gif    {
InBlock.gif            Console.WriteLine("[BaseClass.BaseClass] " + 
InBlock.gif                " PrintInfo method Invoked! ");    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    
ExpandedBlockEnd.gif}

None.gif
None.gif class DerivedClass : BaseClass
ExpandedBlockStart.gif {
InBlock.gif    public DerivedClass() : base(100)
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("Thisdot.gif");    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public DerivedClass(int foo) : this()
ExpandedSubBlockStart.gif    {        
InBlock.gif        Console.WriteLine("[DerivedClass.Derived] " +
InBlock.gif             "Constructor called");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public override void PrintInfo()
InBlock.gif//        public void PrintInfo()
ExpandedSubBlockStart.gif
    {
InBlock.gif        base.PrintInfo();
InBlock.gif            Console.WriteLine("[DerivedClass.Derived] " +
InBlock.gif                 " PrintInfo method Invoked!!!");    
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif class DerivedClass2 : DerivedClass
ExpandedBlockStart.gif {
InBlock.gif    public DerivedClass2() : base(100)
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("Thisdot.gif");    
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public DerivedClass2(int foo) : this()
ExpandedSubBlockStart.gif    {        
InBlock.gif        Console.WriteLine("[DerivedClass.Derived] " +
InBlock.gif             "Constructor called");
ExpandedSubBlockEnd.gif    }

InBlock.gif    
InBlock.gif    public override void PrintInfo()
InBlock.gif//        public void PrintInfo()
ExpandedSubBlockStart.gif
    {
InBlock.gif        base.PrintInfo();
InBlock.gif            Console.WriteLine("[DerivedClass2.Derived] " +
InBlock.gif                 " PrintInfo method Invoked222!!!");    
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

None.gif
None.gif class DefaultInitializer
ExpandedBlockStart.gif {
InBlock.gif    public static void Main()
ExpandedSubBlockStart.gif    {
InBlock.gif        Console.WriteLine("[Main] Instantiating a " +
InBlock.gif           "DerivedClass object");
InBlock.gif        DerivedClass2 derived = new DerivedClass2(100);
InBlock.gif        derived.PrintInfo();
ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
        
None.gif

base5.JPG

       从IL代码看到,它依然指向了最高层次的那个父类的。但如果此时增加base.PrintInfo()代码,却依然如我们希望的那样只是调用父类DerivedClass2的相关函数。

重写父类一般的函数的这种方式到了IL这个层面的原来是如此的,是否和想象中的不同?




       对于第2种情况,当父类的构造函数需要带参数的,且情况比较复杂时候,用base来显式说明具体调用需要的构造函数是十分方便的,如果不特别指定则缺省调用不带参数的那个,如果父类没有这个不带参数的构造函数则会出错的。代码如上面的例子也可见一斑。

       问题是如果希望和一般函数重写那样,到子类的构造函数完全不需要父类的构造函数方式呢?构造函数似乎不可以写成override的方式的。

       想到增加一个决定父类如何构造的参数,父类根据子类传入的参数来决定如何初始化,但是这样初始化最终决定权还是在父类那边,代码如下:

None.gif using System;
None.gif
None.gif enum ClassType
ExpandedBlockStart.gif {
InBlock.gif    NoneInit,
InBlock.gif    Init1,
InBlock.gif    Init2
ExpandedBlockEnd.gif}

None.gif
None.gif class BaseClass
ExpandedBlockStart.gif {
InBlock.gif
InBlock.gif    public BaseClass(ClassType aType)
ExpandedSubBlockStart.gif    {
InBlock.gif           switch(aType)
ExpandedSubBlockStart.gif           {
InBlock.gif              case ClassType.NoneInit:
InBlock.gif                 break;
InBlock.gif              case ClassType.Init1:
InBlock.gif                 break;
InBlock.gif              case ClassType.Init2:
InBlock.gif                 break;
InBlock.gif              default:                 
InBlock.gif                 break;    
ExpandedSubBlockEnd.gif           }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

     
       有没有象override那样的实现机制呢,继承的子类比较灵活,即使有改动对父类更改也不多?72_72.gif72_72.gif72_72.gif


本文转自风前絮~~博客园博客,原文链接:http://www.cnblogs.com/windsails/archive/2004/10/28/57794.html,如需转载请自行联系原作者

相关文章
|
4月前
|
存储 前端开发 数据安全/隐私保护
Base64详解:从编码原理到应用实践
Base64详解:从编码原理到应用实践
|
12月前
|
数据安全/隐私保护 C++ Python
Base32系列编码 代码实现过程
Base32系列编码 代码实现过程
144 0
|
编解码 算法 数据安全/隐私保护
一看就懂的Base64算法原理及应用
Base64是一种基于64个字符的编码算法,根据RFC 2045的定义:“Base64内容传送编码是以一种任意8位字节序列组合的描述形式,这种形式不易被人直接识别"。经过Base64编码后的数据会比原始数据略长,为原来的4/3倍。字符串的字符数是以4位单位的整数倍。
291 0
BUUCTF--Reverse--easyre(非常简单的逆向)WP
BUUCTF--Reverse--easyre(非常简单的逆向)WP
|
前端开发
前端学习案例-base64的实现原理1
前端学习案例-base64的实现原理1
56 0
前端学习案例-base64的实现原理1
|
前端开发
前端学习案例-base64的实现原理2
前端学习案例-base64的实现原理2
62 0
前端学习案例-base64的实现原理2
|
缓存 运维 NoSQL
|
编解码 算法 安全
一文看懂Base64原理(并使用java实现)
Base64编码解码算是网络安全领域的很小而且很简单的一个知识点了,虽然简单但是应用场景却极其广泛,可以这样说,开发者要是不懂Base64,基本上可以告别程序猿生涯了。这篇文章从原理入手,并给出java的Base64实现。方便你掌握Base64。
264 0
一文看懂Base64原理(并使用java实现)
|
XML 存储 算法
为啥要 base64 编码?
为啥要 base64 编码?
266 0
为啥要 base64 编码?
|
XML 存储 JSON
基础知识 - 为什么要使用 Base64 编码,有哪些情景需求?
基础知识 - 为什么要使用 Base64 编码,有哪些情景需求?
394 0