Spiga

C#学习笔记(二):构造函数的执行序列

2006-01-09 08:34 by 努力学习的小熊, 1364 visits, 收藏, 编辑

任何构造函数都可以进行配置,以便在执行自己的代码前调用其它构造函数。

我们首先看看在创建类的实例时会发生什么情况。为了实例化派生的类,必须实例化它的基类。而要实例化这个基类,又必须实例化这个基类的基类,这样一直实例化到System.Object为止。结果是无论使用什么构造函数实例化一个类,总是要先调用System.Object.Object()

如果对一个类使用非默认的构造函数,默认的情况是在其基类上使用匹配于这个构造函数签名的构造函数。如果没有找到这样的构造函数,就使用基类的默认构造函数(根类System.Object总是要使用默认的构造函数,因为这个类没有非默认的构造函数)。

我们以下面这个小代码段例子作一些说明:

     public class MyBaseClass
     {
         public MyBaseClass()
         {
         }
 
         public MyBaseClass(int i)
         {
         }
     }
 
     public class MyDerivedClass : MyBaseClass
     {
         public MyDerivedClass()
         {
         }
 
         public MyDerivedClass(int i)
         {
         }
 
         public MyDerivedClass(int i, int j)
         {
         }
     }

如果以下面的方式实例化MyDerivedClass

     MyDerivedClass myObj = new MyDerivedClass();

则发生下面的一系列事件:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass()构造函数。
    3.执行MyDerivedClass.MyDerivedClass()构造函数。 

如果使用下面的语句:

MyDerivedClass myObj = new MyDerivedClass(4);

则发生下面的—系列事件:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。 

如果使用下面的语句:

MyDerivedClass myObj = new MyDerivedClass(4,8);

则发生下面的—系列事件:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass()构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。 

有时需要对发生的事件进行更多的控制。例如,在上面的实例化范例中,需要有下面的事件序列:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i, int j)构造函数。

使用这个序列可以在编写MyBaseClass(int i)中使用int i参数的代码,即MyDerivedClass(int i, int j)构造函数要做的工作比较少,只需要处理int j参数(假定int i参数在两种情况下有相同的含义)。我们仅需指定在派生类的构造函数定义中所使用的基类的构造函数,如下所示:

     public class MyDerivedClass : MyBaseClass
     {
          ……
         public MyDerivedClass(int i, int j) : base(i)
         {
         }
     }

其中,base关键字指定.NET实例化过程,以使用基类中匹配指定签名的构造函数。这个例子中使用一个int参数,所以在实例化序列中应调用MyBaseClass(int i)

同时我们也可以使用这个关键字指定基类构造函数的字面值。

     public class MyDerivedClass : MyBaseClass
     {
         public MyDerivedClass() : base(5)
         {
         }
         ……
     }

这段代码将执行以下序列:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass()构造函数。 

下面我们介绍另一个关键字this。这个关键字指定在调用指定的构造函数前,.NET实例化过程对当前类使用非默认的构造函数。

     public class MyDerivedClass : MyBaseClass
     {
         public MyDerivedClass() : this(5,6)
         {
         }
         ……
         public MyDerivedClass(int i, int j) : base(i)
         {
         }
     }

这段代码将执行以下序列:
        1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i,int j)构造函数。
    4.执行MyDerivedClass.MyDerivedClass()构造函数。 

唯一的限制是使用thisbase关键字只能指定一个构造函数。但是如上所示,这并不是一个很严厉的限制,按照上述方式仍可以构造相当复杂的执行序列。

Add your comment

10 条回复

  1. #1楼 州[未注册用户]2006-10-21 22:21
    哥们:精彩哦。比那些只抄书,而并不真正懂c#的“教授”NB多了。。。。
     回复 引用   
  2. #2楼 迪迪[未注册用户]2008-03-18 15:48
    下面我们介绍另一个关键字this。这个关键字指定在调用指定的构造函数前,.NET实例化过程对当前类使用非默认的构造函数。

    public class MyDerivedClass : MyBaseClass
    {
    public MyDerivedClass() : this(5,6)
    {
    }
    ……
    public MyDerivedClass(int i, int j) : base(i)
    {
    }
    }

    这段代码将执行以下序列:
    1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i,int j)构造函数。
    4.执行MyDerivedClass.MyDerivedClass()构造函数。


    这里的是哪个实例化范例?
    是MyDerivedClass myObj = new MyDerivedClass();
    还是:MyDerivedClass myObj = new MyDerivedClass(4,8);
     回复 引用   
  3. #3楼 迪迪[未注册用户]2008-03-18 22:45
    1MyDerivedClass myObj = new MyDerivedClass(4);

    则发生下面的—系列事件:
    1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。


    应该是:
    1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。

    不信你试试看.
     回复 引用   
  4. #4楼 迪迪[未注册用户]2008-03-18 22:46
    上面发错了,重发:

    MyDerivedClass myObj = new MyDerivedClass(4);

    则发生下面的—系列事件:
    1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(int i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。


    应该是:
    1.执行System.Object.Object()构造函数。
    2.执行MyBaseClass.MyBaseClass(i)构造函数。
    3.执行MyDerivedClass.MyDerivedClass(int i)构造函数。

    不信你试试看.
     回复 引用   
  5. #5楼 二把刀      2008-04-07 09:23
    非常好文章,看完后豁然开朗!
     回复 引用 查看   
  6. #6楼 小鹤儿      2010-12-02 09:43
    不错,写得很清楚……
     回复 引用 查看   
  7. #7楼 Tedy      2011-11-01 11:09
    @迪迪
    MyDerivedClass myObj = new MyDerivedClass();
     回复 引用 查看