假设我有一个名为“ABC”的类
Class ABC:IDisposable
{
public string name {get;set;}
public string Method1()
{
// Implements
}
//end of class
}
我从其他人那里听说你应该总是继承IDisposable
来释放内存创建上面这类的对象:
using(ABC objABC = new ABC())
{
objABC.Method1();
}
但是还有其他方法可以调用和使用上面的类和方法,例如
private string testmethods()
{
ABC objABC = new ABC();
string test = objABC.Method1();
// I want to know this above `objABC` 's memory is free after finish `testmethods()`?
// we can also call using this like below
string test2 = new ABC().Method1();
}
我想知道实现这一目标的最佳途径是什么?
我还想知道,testmethods()
来电结束后对象内存会自动清除吗?
答案 0 :(得分:6)
假设ABC
没有保留任何非托管资源,则不需要实现IDisposable
。一旦没有对它们的实时引用,C#中的对象就有资格进行垃圾收集,当垃圾收集器运行时,它们使用的内存将自动释放。
如果您的类只拥有需要释放的非托管资源,或者拥有其他实现IDisposable
的托管对象,那么它们只需要实现IDisposable
。如果您的类拥有非托管资源,那么如果在收集Dispose
之前未调用objABC
,则还应实施finalizer以释放它们。
因此,第二种方法是首选方法,objABC.Method1
在{{1}}返回后有资格进行收集(实际上可以尽快收集,但这是一种内部GC机制)。请注意,它不会在此时自动释放,但仅在GC下次运行时才会释放,假设没有更多的引用。
答案 1 :(得分:5)
存在Disposable pattern以释放非托管资源。因此,除非您的C#程序调用某些本机API,或者使用自己实现Disposable模式的类,让您的类实现IDisposable并始终使用using
处理它是完全没有意义的。
答案 2 :(得分:2)
IDisposable接口设计用于支持Disposable模式,用于显式释放除内存资源之外的 :因为垃圾收集器(GC)只能处理内存,其他资源如打开文件,数据库连接,各种不受管理 资源等应该明确关闭。
http://msdn.microsoft.com/en-us/library/fs2xkftw.aspx
使用IDisposable的典型方案是
// MyResourceWrapper is IDisposable
using (MyResourceWrapper wrapper = new MyResourceWrapper()) { // <- acquire resource
... // <- work with resource
} // <- free resource
例如
String text;
using (StreamReader sr = new StreamReader(@"C:\MyText.txt")) { // resource (file stream) opened
text = sr.ReadToEnd(); // <- resource (file stream) utilized (read)
} // <- resource freed (file stream closed)
如果您的班级中没有任何资源可供使用,则无需实施IDisposable
答案 3 :(得分:1)
首先问自己 - 你会在问题的第二个代码部分写一个try-finally块吗?如果是,那么你会在finally块中写什么?如果您的ABC类正在使用非托管资源,并且它实现了IDisposable接口,那么您将在finally块中调用Dispose方法。
using(ABC objABC = new ABC())
{
objABC.Method1();
}
相当于: -
ABC objABC = new ABC()
try
{
objABC.Method1();
}
finally
{
objABC..Dispose()
}
现在,如果您没有在ABC类中处理任何非托管的内容,为什么要在此类上实现IDisposable接口?
具有非托管资源的类的示例是实现IDisposable的SqlConnection,并且在其Dispose方法中它处理所有这些非托管资源。这就是为什么你看到人们使用如下代码: -
using (SqlConnection connection = new SqlConnection(connectionString))
{
...........
}