摘 要:构造函数与析构函数是一个类中看似较为简单的两类函数,但在实际运用过程中总会出现一些意想不到的运行错误。本文将较系统的介绍构造函数与析构函数的原理及在c#中的运用,以及在使用过程中需要注意的若干事项。
关键字:构造函数;析构函数;垃圾回收器;非托管资源;托管资源
一.构造函数与析构函数的原理
作为比c更先进的语言,c#提供了更好的机制来增强程序的安全性。c#编译器具有严格的类型安全检查功能,它几乎能找出程序中所有的语法问题,这的确帮了程序员的大忙。但是程序通过了编译检查并不表示错误已经不存在了,在“错误”的大家庭里,“语法错误”的地位只能算是冰山一角。级别高的错误通常隐藏得很深,不容易发现。
根据经验,不少难以察觉的程序错误是由于变量没有被正确初始化或清除造成的,而初始化和清除工作很容易被人遗忘。微软利用面向对象的概念在设计c#语言时充分考虑了这个问题并很好地予以解决:把对象的初始化工作放在构造函数中,把清除工作放在析构函数中。当对象被创建时,构造函数被自动执行。当对象消亡时,析构函数被自动执行。这样就不用担心忘记对象的初始化和清除工作。
二.构造函数在c#中的运用
构造函数的名字不能随便起,必须让编译器认得出才可以被自动执行。它的命名方法既简单又合理:让构造函数与类同名。除了名字外,构造函数的另一个特别之处是没有返回值类型,这与返回值类型为void的函数不同。如果它有返回值类型,那么编译器将不知所措。在你可以访问一个类的方法、属性或任何其它东西之前, 第一条执行的语句是包含有相应类的构造函数。甚至你自己不写一个构造函数,也会有一个缺省构造函数提供给你。
class testclass { public testclass(): base() {} // 由clr提供 } |
class testclass { public testclass(): base() {} } |
using system; class point { public double x, y; public point() { this.x = 0; this.y = 0; } public point(double x, double y) { this.x = x; this.y = y; } … } class test { static void main() { point a = new point(); point b = new point(3, 4); // 用构造函数初始化对象 … } } |
using system.data; class employee { private static dataset ds; static employee() { ds = new dataset(...); } ... } |
class a { private int x; public a( ) { x = 0; } public a( int i ) { x = i; } }; class b : a { private int y; public b( ) { y = 0; } public b( int i ) { y = i; } public b( int i, int j ):a(i) { y = j; } }; b b1 = new b(); //执行基类a的构造函数a(),再执行派生类的构造函数b() b b2 = new b(1); //执行基类a的构造函数a(),再执行派生类的构造函数b(int) b b3 = new b(0,1); //执行执行基类a的构造函数a(int) ,再执行派生类的 |
class a { private int x; public a( int i ) { x = i; } }; class b : a { private int y; public b():a(i) { y = 0; } public b(int i):a(i) { y = i; } public b(int i, int j):a(i) { y = j; } }; |
public class resourceholder { … ~resourceholder() { // 这里是清理非托管资源的用户代码段 } } |
新闻热点
疑难解答