C#中的析构函数
来源:互联网 发布:淘宝女装网 编辑:程序博客网 时间:2024/05/06 11:51
引言
在企业应用开发世界,性能,灵活性和安全性是最重要的。我作为一个VC++程序员开始我的职业生涯,并且在一个晴朗的早晨,我被转到了Web开发部。像每个C++程序员一样,我也很失落。我想每个像Tom,Dick甚至Harry能用HTML编程。然而,不久我就发现真正的挑战是生产高性能的,灵活的可靠的应用程序。综上所述,Web环境松耦合的,不分国界的本质将使你永远神往。
为了制作高性能的灵活的应用程序,用最优化的方式使用你的资源是至关重要的。一个技巧是尽可能晚地使用你的资源并且在使用后尽快释放它。我在这里的意图是描述在C#中的对象清除机制。
解构器
我们知道,‘解构器’被用来清除类的事例。当我们在C#中使用解构器是,我们必须记住以下几点:
- 一个类只能有一个解构器。
- 解构器不能被继承或重载。
- 解构器不能被调用。他们是自动被(编译器)调用的。
- 解构器不能带修饰或参数。
下面是类
MyClass
解构器的一个声明:~ MyClass()
{
// Cleaning up code goes here
}
protected override void Finalize()
{
try
{
// Cleaning up .
}
finally
{
base.Finalize();
}
}
现在,让我们看一个解构器怎样被调用的例子。我们有三个类
A,B
和C
。B
派生自A
,C
派生自B
。每个类有它们自己的构造器和解构。在类App
的main
函数中,我们创建C的
对象。using System;
class A
{
public A()
{
Console.WriteLine("Creating A");
}
~A()
{
Console.WriteLine("Destroying A");
}
}
class B:A
{
public B()
{
Console.WriteLine("Creating B");
}
~B()
{
Console.WriteLine("Destroying B");
}
}
class C:B
{
public C()
{
Console.WriteLine("Creating C");
}
~C()
{
Console.WriteLine("Destroying C");
}
}
class App
{
public static void Main()
{
C c=new C();
Console.WriteLine("Object Created ");
Console.WriteLine("Press enter to Destroy it");
Console.ReadLine();
c=null;
//GC.Collect();
Console.Read();
}
}
正如我们预料的,基类的构造器将会被执行并且程序会等待用户按‘enter’。当这个发生,我们把类C的对象置为null.但解构器没有被执行..!!??正像我们所说的,程序员无法控制解构器何时被执行因为这是由垃圾搜集器决定的。但程序退出时解构器被调用了。你能通过重定向程序的o/p到文本文件来检查这个。我将它输出在这里。注意到基类的解构器被调用了,因为在背后base.Finalize()被调用了。
Creating A
Creating B
Creating C
Object Created
Press enter to Destroy it
Destroying C
Destroying B
Destroying A
所以,如果一旦你使用完对象你就想调用解构器,你该怎么做?有两个方法:
实现IDisposable接口
IDisposable
接口包括仅有的一个公共方法,其声明为void Dispose()
。我们能实现这个方法来关闭或释放非托管资源如实现了这个接口的类事例所控制的文件,流,和句柄等。这个方法被用做所有任务联合对象的资源释放。当实现了这个方法,对象必须寻求确保所有拥有的资源被继承结构中关联的资源也释放(不能把握,翻不出来)。class MyClass:IDisposable
{
public void Dispose()
{
//implementation
}
}
当我们实现了
IDisposable
接口时,我们需要规则来确保Dispose
被适当地调用。在这里重载了
Dispose(bool)
来做清理工作,并且所有的清理代码都仅写在这个方法中。这个方法被解构器和IDisposable.Dispose()
两着调用。我们应该注意Dispose(bool)
没有在任何地方被调用除了在IDisposable.Dispose()
和解构器中。using (MyClass objCls =new MyClass())
{
}
当控制从
using
块通过成功运行到结束或者抛出异常退出时,MyClass
的IDispose.Dispose()
将会被执行。记住你例示的对象必须实现System.IDisposable
接口。using
语句定义了哪个对象将被清除的一个范围。 尽管如此我们花费一些时间实现IDisposable
接口,如果客户不能合适地调用它们会怎样?为此C#有一个酷的解决方案。‘using
’代码块。它看起来像这样:结论当一个客户调用
IDisposable.Dispose()
时,客户特意地想要清理托管的和非托管资源,并且因此完成清理工作。有一件你必须注意的事情是我们在清理资源之后立即调用了GC.SupressFinalize(this)
。这个方法通知垃圾搜集器不需要调用解构器,因为我们已经做了清理。注意上面的例子,解构器使用参数
false
调用Dispose
。这里,我们确信垃圾搜集器搜集了托管资源。我们仅仅做非托管资源的清理。Public class MyClass:IDisposable
{
private bool IsDisposed=false;
public void Dispose()
{
Dispose(true);
GC.SupressFinalize(this);
}
protected void Dispose(bool Diposing)
{
if(!IsDisposed)
{
if(Disposing)
{
//Clean Up managed resources
}
//Clean up unmanaged resources
}
IsDisposed=true;
}
~MyClass()
{
Dispose(false);
}
}
联合使用解构器和IDisposable接口-
调用垃圾搜集器来清理。
-
实现
IDisposable
的Dispose
方法。
调用垃圾搜集器
你能通过调用
GC.Collect
方法强制垃圾搜集器来清理内存,但在大多数情况下,这应该避免因为它会导致性能问题。在上面的程序中,在GC.Collect()
处移除注释。编译并运行它。现在,你能看到解构器在控制台中被执行了。 -
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C#中的析构函数
- C# 中的析构函数
- C#中的析构函数
- C#中的析构函数和垃圾回收器
- C#中的函数指针
- C#中的构造函数
- C#中的时间函数
- C#中的随机函数
- 语音识别在家电遥控器中的应用
- asp/asp.net中遍历树型结构.
- QQ被盗了的可以这样搞回来
- QQ完全资费明细表!
- 关于IDE的话题
- C#中的析构函数
- listview使用(摘自pb 帮助文件)
- 抄袭的人是可耻的
- CORELDRAW向PHOTOSHOP格式转换之比较
- 在web中使用toolbar的DorpDownList
- 运十回来了
- VC中利用多线程技术实现线程之间的通信
- slony1-1.0.2 使用
- 为了学习WinCE嵌入式编程,又开始学起了MFC