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,系统就不会自动为类提供默认构造函数。
- 结构体
- 编译器会强制自动添加默认构造函数,并且初始化所有字段为默认值。所以程序员无法自己添加默认构造函数。
- 可以有多个接受不同参数的构造函数,参数类型不同,个数不同都可以。
- 结构体没有析构函数
- 类
- 如果类是非static,编译器会自动提供默认构造函数。如果程序员自己定义了任何构造函数,系统就不会再提供默认构造函数。
- 可以使用base来调用基类的构造函数,如果基类没有默认构造函数,派生类必须使用base显式调用基类构造函数。
- 可以使用this来调用同一个类中的另一个构造函数。
- 私有构造函数,可以用来设计单类(Singleton)或者关闭静态类的构造。
- 子类会自动调用父类(基类)的构造函数,从父类(基类)开始到子类。
- 静态构造函数
- 静态构造函数,无参数,也无修饰符。
- 在创建第一个实例或者引用任何静态成员之前,自动调用静态构造函数初始化类,所以无法直接调用静态构造函数,程序员也无法直接控制静态函数的调用。
- 如果静态函数引发异常,将不会再次调用,并且在程序运行所在的应用程序域的生存期间,保持未初始化。
- 一个类只能有一个析构函数
- 无法继承和重载类的析构函数
- 程序员无法调用类的析构函数,因为它是由GC控制自动调用,何时被调用,无法控制。由于不确定性,所以析构函数不应该用于执行一些在程序特定点必须执行的操作。
- 析构函数无参数和修饰符,子类析构函数隐式对基类调用析构函数,由子类到父类(基类)。
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: }
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: }
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++是不同,不能在编码的时候想当然!
作者:点滴点点滴滴
本文版权归作者所有,欢迎转载,但未经作者同意时必须保留此段声明,且须在文章页面显著位置给出原文连接,否则作者保留追究法律责任的权利。