IDisposable 接口实现示例
托管的概念是在.net框架诞生后出现的。用比较通俗的话解释就是运行在.net框架下,并受.net框架管理的应用或其他组件称为托管的,反之为非托管的。
也就是说用.net平台开发出来的程序应该就是托管的了,而在.net以前开发的程序都属于非托管的。但是非托管的程序完全可以通过在.net平台下重新生成而变成托管的。
.NET平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代码中使用了一个COM对象。
最简单的办法,可以通过实现protected void Finalize()来释放非托管资源,因为GC在释放对象时会检查该对象是否实现了Finalize()方法,如果是则调用它。但这样会降低效率……
有一种更好的,那就是通过实现一个接口显式的提供给客户调用端手工释放对象的方法,而不是傻傻的等着GC来释放我们的对象(何况效率又那么低)。
System 命名空间内有一个 IDisposable 接口,拿来做这事非常合适,就省得我们自己再声明一个接口了。
另外,这种实现并不一定要使用了非托管资源后才用,如果你设计的类会在运行时有大些的实例(像GIS 中的Geometry),为了优化程序性能,你也可以通过实现该接口让客户调用端在确认不需要这些对象时手工释放它们。
示例代码
using System;
using System.Collections.Generic;
using System.Text;
namespace DisposableDemo
{
class Program
{
class Class1 : IDisposable
{
//析构函数,编译后变成 protected void Finalize(),GC会在回收对象前调用该方法
~Class1()
{
Dispose(false);
}
//通过实现该接口,客户可以显式地释放对象,而不需要等待GC来释放资源,据说那样会降低效率
void Dispose()
{
Dispose(true);
}
//将释放非托管资源设计成一个虚函数,提供在继承类中释放基类的资源的能力
protected virtual void ReleaseUnmanageResources()
{
//Do something...
}
//私有函数用以释放非托管资源
private void Dispose(bool disposing)
{
ReleaseUnmanageResources();
//为true时表示是客户显式调用了释放函数,需通知GC不要再调用对象的Finalize方法
//为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC你不要调用我的Finalize方法
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
static void Main(string[] args)
{
//tmpObj1没有手工释放资源,就等着GC来慢慢的释放它
Class1 tmpObj1 = new Class1();
//tmpObj2调用了Dispose方法,比等着GC来释放它效率要高一些
Class1 tmpObj2 = new Class1();
((IDisposable)tmpObj2).Dispose();
}
}
}
也就是说用.net平台开发出来的程序应该就是托管的了,而在.net以前开发的程序都属于非托管的。但是非托管的程序完全可以通过在.net平台下重新生成而变成托管的。
.NET平台在内存管理方面提供了GC(Garbage Collection),负责自动释放托管资源和内存回收的工作,但它无法对非托管资源进行释放,这时我们必须自己提供方法来释放对象内分配的非托管资源,比如你在对象的实现代码中使用了一个COM对象。
最简单的办法,可以通过实现protected void Finalize()来释放非托管资源,因为GC在释放对象时会检查该对象是否实现了Finalize()方法,如果是则调用它。但这样会降低效率……
有一种更好的,那就是通过实现一个接口显式的提供给客户调用端手工释放对象的方法,而不是傻傻的等着GC来释放我们的对象(何况效率又那么低)。
System 命名空间内有一个 IDisposable 接口,拿来做这事非常合适,就省得我们自己再声明一个接口了。
另外,这种实现并不一定要使用了非托管资源后才用,如果你设计的类会在运行时有大些的实例(像GIS 中的Geometry),为了优化程序性能,你也可以通过实现该接口让客户调用端在确认不需要这些对象时手工释放它们。
示例代码
using System;
using System.Collections.Generic;
using System.Text;
namespace DisposableDemo
{
class Program
{
class Class1 : IDisposable
{
//析构函数,编译后变成 protected void Finalize(),GC会在回收对象前调用该方法
~Class1()
{
Dispose(false);
}
//通过实现该接口,客户可以显式地释放对象,而不需要等待GC来释放资源,据说那样会降低效率
void Dispose()
{
Dispose(true);
}
//将释放非托管资源设计成一个虚函数,提供在继承类中释放基类的资源的能力
protected virtual void ReleaseUnmanageResources()
{
//Do something...
}
//私有函数用以释放非托管资源
private void Dispose(bool disposing)
{
ReleaseUnmanageResources();
//为true时表示是客户显式调用了释放函数,需通知GC不要再调用对象的Finalize方法
//为false时肯定是GC调用了对象的Finalize方法,所以没有必要再告诉GC你不要调用我的Finalize方法
if (disposing)
{
GC.SuppressFinalize(this);
}
}
}
static void Main(string[] args)
{
//tmpObj1没有手工释放资源,就等着GC来慢慢的释放它
Class1 tmpObj1 = new Class1();
//tmpObj2调用了Dispose方法,比等着GC来释放它效率要高一些
Class1 tmpObj2 = new Class1();
((IDisposable)tmpObj2).Dispose();
}
}
}
-*- 此文章为本人发呆时 ctrl+c , ctrl+v 的结果. 如果损害到您的利益, 可以联系我 QQ: 248078462 -*-