base想到...
base 是C#中77个(如果没有记错的话 )关键字之一,在MSDN文档中列举的主要作用是两个:
)关键字之一,在MSDN文档中列举的主要作用是两个:
1. 调用基类上已被其他方法重写的方法。
2. 指定创建派生类实例时应调用的基类构造函数。
注意点:基类访问只能在构造函数、实例方法或实例属性访问器中进行,从静态方法中使用base关键字是错误的。
对于第1点,作用十分明显,重写了父类函数,但是又需要调用父类函数的时候就需要用到了,例如下面的代码:
 using System;
using System;
 class BaseClass
class BaseClass {
{ public BaseClass()
    public BaseClass() {
    { Console.WriteLine("[BaseClass.BaseClass] " +
        Console.WriteLine("[BaseClass.BaseClass] " +  "Constructor called");
           "Constructor called");            }
    } 
     public BaseClass(int foo)
    public BaseClass(int foo) {
    { Console.WriteLine("[BaseClass.BassClass] " +
            Console.WriteLine("[BaseClass.BassClass] " + " Argument parameter is {0}", foo.ToString());
               " Argument parameter is {0}", foo.ToString());     }
    } 
     public virtual void PrintInfo()
    public virtual void PrintInfo() {
    { Console.WriteLine("[BaseClass.BaseClass] " +
            Console.WriteLine("[BaseClass.BaseClass] " +  " PrintInfo method Invoked! ");
                " PrintInfo method Invoked! ");     }
    } 
     
     }
}
 class DerivedClass : BaseClass
class DerivedClass : BaseClass {
{ public DerivedClass() : base(100)
    public DerivedClass() : base(100) {
    { Console.WriteLine("This
        Console.WriteLine("This ");
");     }
    } 
     public DerivedClass(int foo) : this()
    public DerivedClass(int foo) : this() {
    {         Console.WriteLine("[DerivedClass.Derived] " +
        Console.WriteLine("[DerivedClass.Derived] " + "Constructor called");
             "Constructor called"); }
    } 
     public override void PrintInfo()
    public override void PrintInfo() //        public void PrintInfo()
//        public void PrintInfo() {
    { //        base.PrintInfo();
//        base.PrintInfo(); Console.WriteLine("[DerivedClass.Derived] " +
            Console.WriteLine("[DerivedClass.Derived] " + " PrintInfo method Invoked!!!");
                 " PrintInfo method Invoked!!!");     }
    } }
}
 class DefaultInitializer
class DefaultInitializer {
{ public static void Main()
    public static void Main() {
    { Console.WriteLine("[Main] Instantiating a " +
        Console.WriteLine("[Main] Instantiating a " + "DerivedClass object");
           "DerivedClass object"); DerivedClass derived = new DerivedClass(100);
        DerivedClass derived = new DerivedClass(100); derived.PrintInfo();
        derived.PrintInfo(); }
    } }
}        
结果和作用都是大家预期的。
用ildasm来看一下,这个过程在IL代码中是如何进行的?
调用override的函数,是指回去父类中去的,但是调用的代码效果却又不是父类中的代码,呵呵~~
而在没有override时候呢, 则是这样的:
重写后的函数调用父类在增加了base.PrintInfo();后在IL可以看到,其实它是直接调用父类中函数的:
增加了base.PrintInfo();后:
没有增加:
可见重写函数中是直接调用父类对应函数的。
两层类结构的IL代码如此,那么三层呢?IL出现的是最上层的类调用还是父类调用呢?
用下面的代码:
 using System;
using System;
 class BaseClass
class BaseClass {
{ public BaseClass()
    public BaseClass() {
    { Console.WriteLine("[BaseClass.BaseClass] " +
        Console.WriteLine("[BaseClass.BaseClass] " +  "Constructor called");
           "Constructor called");            }
    } 
     public BaseClass(int foo)
    public BaseClass(int foo) {
    { Console.WriteLine("[BaseClass.BassClass] " +
            Console.WriteLine("[BaseClass.BassClass] " + " Argument parameter is {0}", foo.ToString());
               " Argument parameter is {0}", foo.ToString());     }
    } 
     public virtual void PrintInfo()
    public virtual void PrintInfo() {
    { Console.WriteLine("[BaseClass.BaseClass] " +
            Console.WriteLine("[BaseClass.BaseClass] " +  " PrintInfo method Invoked! ");
                " PrintInfo method Invoked! ");     }
    } 
     
     }
}
 class DerivedClass : BaseClass
class DerivedClass : BaseClass {
{ public DerivedClass() : base(100)
    public DerivedClass() : base(100) {
    { Console.WriteLine("This
        Console.WriteLine("This ");
");     }
    } 
     public DerivedClass(int foo) : this()
    public DerivedClass(int foo) : this() {
    {         Console.WriteLine("[DerivedClass.Derived] " +
        Console.WriteLine("[DerivedClass.Derived] " + "Constructor called");
             "Constructor called"); }
    } 
     public override void PrintInfo()
    public override void PrintInfo() //        public void PrintInfo()
//        public void PrintInfo() {
    { base.PrintInfo();
        base.PrintInfo(); Console.WriteLine("[DerivedClass.Derived] " +
            Console.WriteLine("[DerivedClass.Derived] " + " PrintInfo method Invoked!!!");
                 " PrintInfo method Invoked!!!");     }
    } }
}
 class DerivedClass2 : DerivedClass
class DerivedClass2 : DerivedClass {
{ public DerivedClass2() : base(100)
    public DerivedClass2() : base(100) {
    { Console.WriteLine("This
        Console.WriteLine("This ");
");     }
    } 
     public DerivedClass2(int foo) : this()
    public DerivedClass2(int foo) : this() {
    {         Console.WriteLine("[DerivedClass.Derived] " +
        Console.WriteLine("[DerivedClass.Derived] " + "Constructor called");
             "Constructor called"); }
    } 
     public override void PrintInfo()
    public override void PrintInfo() //        public void PrintInfo()
//        public void PrintInfo() {
    { base.PrintInfo();
        base.PrintInfo(); Console.WriteLine("[DerivedClass2.Derived] " +
            Console.WriteLine("[DerivedClass2.Derived] " + " PrintInfo method Invoked222!!!");
                 " PrintInfo method Invoked222!!!");     }
    } }
}
 class DefaultInitializer
class DefaultInitializer {
{ public static void Main()
    public static void Main() {
    { Console.WriteLine("[Main] Instantiating a " +
        Console.WriteLine("[Main] Instantiating a " + "DerivedClass object");
           "DerivedClass object"); DerivedClass2 derived = new DerivedClass2(100);
        DerivedClass2 derived = new DerivedClass2(100); derived.PrintInfo();
        derived.PrintInfo(); }
    } }
}        
       从IL代码看到,它依然指向了最高层次的那个父类的。但如果此时增加base.PrintInfo()代码,却依然如我们希望的那样只是调用父类DerivedClass2的相关函数。
重写父类一般的函数的这种方式到了IL这个层面的原来是如此的,是否和想象中的不同?
对于第2种情况,当父类的构造函数需要带参数的,且情况比较复杂时候,用base来显式说明具体调用需要的构造函数是十分方便的,如果不特别指定则缺省调用不带参数的那个,如果父类没有这个不带参数的构造函数则会出错的。代码如上面的例子也可见一斑。
问题是如果希望和一般函数重写那样,到子类的构造函数完全不需要父类的构造函数方式呢?构造函数似乎不可以写成override的方式的。
       想到增加一个决定父类如何构造的参数,父类根据子类传入的参数来决定如何初始化,但是这样初始化最终决定权还是在父类那边,代码如下:
 using System;
using System;
 enum ClassType
enum ClassType {
{ NoneInit,
    NoneInit, Init1,
    Init1, Init2
    Init2 }
}
 class BaseClass
class BaseClass {
{
 public BaseClass(ClassType aType)
    public BaseClass(ClassType aType) {
    { switch(aType)
           switch(aType) {
           { case ClassType.NoneInit:
              case ClassType.NoneInit: break;
                 break; case ClassType.Init1:
              case ClassType.Init1: break;
                 break; case ClassType.Init2:
              case ClassType.Init2: break;
                 break; default:
              default:                  break;
                 break;     }
           } }
    } }
}     
       有没有象override那样的实现机制呢,继承的子类比较灵活,即使有改动对父类更改也不多?


 
 
                    
                     
                    
                 
                    
                 
                
            
         
 
         浙公网安备 33010602011771号
浙公网安备 33010602011771号