代码改变世界

C# Constructor and Destructor

2012-05-22 18:43  libiver  阅读(1996)  评论(0编辑  收藏  举报

声明:欢迎任何人和组织转载本blog中文章,但必须标记文章原始链接和作者信息。

本文链接:http://www.cnblogs.com/leezhm/archive/2012/05/22/2513719.html

开拓进取的小乌龟------->cnBlogs 点滴点点滴滴 Blog

          根据今天的C#复习,对构造函数和析构函数进行了一下梳理。它们具体在结构体和类中表现也是很不一样的,比如结构体就不能有析构函数,而且不能包含显式的默认构造函数(因为编译器会自动强制提供,而且初始化所有字段为默认值。C#的默认值表,参考http://msdn.microsoft.com/zh-cn/library/83fhsxwc.aspx)。在这里首先解释下“默认构造函数”,它是指无参数的构造函数,系统会默认添加(如果类是static,则编译器不会提供)。如果我们为类添加了构造函数(无参或者有参),或者类是static,系统就不会自动为类提供默认构造函数。

  • 结构体
    • 编译器会强制自动添加默认构造函数,并且初始化所有字段为默认值。所以程序员无法自己添加默认构造函数。
    • 可以有多个接受不同参数的构造函数,参数类型不同,个数不同都可以。
    • 结构体没有析构函数
       1:      public struct DefaultStruct
       2:      {
       3:          public DefaultStruct() // error CS0568: Structs cannot contain explicit parameterless constructors
       4:          {
       5:          }
       6:   
       7:          public DefaultStruct(int e)
       8:          {
       9:          }
      10:   
      11:          public DefaultStruct(short k)
      12:          {
      13:          }
      14:      }
    • 如果类是非static,编译器会自动提供默认构造函数。如果程序员自己定义了任何构造函数,系统就不会再提供默认构造函数。
    • 可以使用base来调用基类的构造函数,如果基类没有默认构造函数,派生类必须使用base显式调用基类构造函数。
    • 可以使用this来调用同一个类中的另一个构造函数。
    • 私有构造函数,可以用来设计单类(Singleton)或者关闭静态类的构造。
    • 子类会自动调用父类(基类)的构造函数,从父类(基类)开始到子类。
       1:  public class Employee
       2:  {
       3:      private double Salary
       4:      {
       5:          get;
       6:          set;
       7:      }
       8:   
       9:      public Employee(double salary)
      10:      {
      11:          Salary = salary;
      12:      }
      13:   
      14:      //public Employee(double weeklySalary, int NumberOfWeeks)
      15:      //{
      16:      //    Salary = weeklySalary * (double)NumberOfWeeks;
      17:      //}
      18:   
      19:      public Employee(double weeklySalary, int NumberOfWeeks)
      20:          : this(weeklySalary * (double)NumberOfWeeks)
      21:      {
      22:      }
      23:  }
      24:   
      25:  public class Manager : Employee
      26:  {
      27:      public Manager() // error CS1729: 'CSnippets.Classes.Employee' does not contain a constructor that takes 0 arguments
      28:      {
      29:      }
      30:   
      31:      public Manager(double salary):base(salary)
      32:      {
      33:          //
      34:      }
      35:  }
       
    • 静态构造函数
      • 静态构造函数,无参数,也无修饰符。
      • 在创建第一个实例或者引用任何静态成员之前,自动调用静态构造函数初始化类,所以无法直接调用静态构造函数,程序员也无法直接控制静态函数的调用。
      • 如果静态函数引发异常,将不会再次调用,并且在程序运行所在的应用程序域的生存期间,保持未初始化。
    • 一个类只能有一个析构函数
    • 无法继承和重载类的析构函数
    • 程序员无法调用类的析构函数,因为它是由GC控制自动调用,何时被调用,无法控制。由于不确定性,所以析构函数不应该用于执行一些在程序特定点必须执行的操作。
    • 析构函数无参数和修饰符,子类析构函数隐式对基类调用析构函数,由子类到父类(基类)。
       1:      public class First
       2:      {
       3:          public First()
       4:          {
       5:              Trace.WriteLine("First's Constructor is called ... ");
       6:          }
       7:   
       8:          ~First()
       9:          {
      10:              Trace.WriteLine("First's Destructor is called ... ");
      11:          }
      12:      }
      13:   
      14:      public class Second : First
      15:      {
      16:          public Second()
      17:          {
      18:              Trace.WriteLine("Second's Constructor is called ... ");
      19:          }
      20:   
      21:          ~Second()
      22:          {
      23:              Trace.WriteLine("Second's Destructor is called ... ");
      24:          }
      25:      }
      26:   
      27:      public class Third : Second
      28:      {
      29:          public Third()
      30:          {
      31:              Trace.WriteLine("Third's Constructor is called ... ");
      32:          }
      33:   
      34:          ~Third()
      35:          {
      36:              Trace.WriteLine("Third's Destructor is called ... ");
      37:          }
      38:      }
    程序运行,在Output窗口,可以看到如下结果 
       1:  First's Constructor is called ... 
       2:  Second's Constructor is called ... 
       3:  Third's Constructor is called ... 
       4:   
       5:  Third's Destructor is called ... 
       6:  Second's Destructor is called ... 
       7:  First's Destructor is called ... 

             总结:其实这些有很多跟C++是不同,不能在编码的时候想当然!