我可以在同一个类中实现这两个方法吗?
public class MyClass : IDisposable
{
// some implementation
// if i missed to call Dispose() method;
~MyClass()
{
// it means, clear all does not mananage resources
// but dont use Dispose() method
}
public void Dispose()
{
// clear resources
// if i call this method will i can do this:
GC.SuppressFinalize()
// it means dont use Finalizw method for this object
}
}我说的对吗?因为我不能理解这个GC.SuppressFinalize()方法?
发布于 2015-01-30 06:18:56
是的,如您所见,可以实现这两种方法。
通常,如果一个对象可以同时具有托管引用和非托管引用,那么正确的模式是:
public class MyClass : IDisposable
{
~MyClass()
{
Dispose(false);
}
public void Dispose()
{
GC.SuppressFinalize(this);
Dispose(true);
}
public virtual void Dispose(bool disposing)
{
if(disposing)
{
// clear MANAGED references
}
// free UNMANAGED resources
}
}但是你可以根据你的意愿来实现它。这只是一种模式。例如,如果您没有任何非托管资源,并且您的类是密封的(因此您可以确保它永远不会使用任何非托管资源),您可以这样实现它:
public sealed class MyClass : IDisposable
{
public void Dispose()
{
// release managed references
}
}忘了终结器吧。
在第一种模式中,GC.SuppresFinalize(this)正在做的是告诉垃圾收集器在释放对象时不应该调用终结器( ~MyClass()方法):如果您专门调用了Dispose(),那么已经调用了您的虚拟Dispose(bool)函数,那么为什么还要再次调用它呢?
问题在于,C#中的终结器本身是不确定的:您不知道何时会调用它.您甚至无法保证它甚至会被调用(尽管在正常清理过程中,如果它以前没有被调用的话),这就是为什么IDisposable存在的原因,这是一种决定性地释放托管引用的方法,这些引用阻塞了您的对象,释放并释放了它分配的非托管资源。
如果一个对象被GC释放,那么它持有的所有托管引用也将被释放,因此在调用终结器时不需要清除托管引用。
但是,您的应用程序应该尽最大努力释放和释放它所拥有的任何非托管资源。
如果您忘记使用Dispose(),那么它们应该有最后的机会获得释放(当GC收集对象时,或者在应用程序运行时进行最后的清理时)。在正常模式中,您还实现了终结器,如果以前没有这样做,则告诉它清理非托管资源。
请注意,与流行的观点相反,对Dispose()的调用没有什么特别之处,它只是一个方法调用:如果您愿意,可以将它称为FreeMyObject()或FooBar()。它不会使垃圾收集器释放任何内存。有一个使用IDisposable的模式,它非常重要,它有自己的语言语法构造( using块),但它只是一个模式。您可以在不实现Dispose()的情况下执行与IDisposable相同的操作。
https://stackoverflow.com/questions/28230183
复制相似问题