我有一个类,它具有一些非托管资源。我的类实现了IDisposable
接口,在Dispose()
方法中释放非托管资源。我必须调用Dispose()
方法吗?还是它会自动被调用?垃圾回收器会调用它吗?
我有一个类,它具有一些非托管资源。我的类实现了IDisposable
接口,在Dispose()
方法中释放非托管资源。我必须调用Dispose()
方法吗?还是它会自动被调用?垃圾回收器会调用它吗?
Dispose()
方法不会自动调用。如果存在终结器,则它将被自动调用。实现IDisposable
接口提供了一种让类的用户提前释放资源的方式,而不必等待垃圾回收器。
客户端首选的方法是使用using
语句,即使有异常也可以处理自动调用Dispose()
。
一个正确的IDisposable
实现应该如下:
class MyClass : IDisposable
{
private bool disposed = false;
void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!disposed)
{
if(disposing)
{
// Manual release of managed resources.
}
// Release unmanaged resources.
disposed = true;
}
}
~MyClass() { Dispose(false); }
}
如果类的用户调用了 Dispose()
,则直接进行清理。如果对象被垃圾回收器捕获,则调用 Dispose(false)
进行清理。请注意,当从终结器(~MyClass
方法)调用时,托管引用可能无效,因此只能释放非托管资源。
你需要手动调用这个方法,可能是在一个类似下面的结构中(假设"MyClass"实现了"IDisposable")
using(var myclass = new MyClass())
{
// do something with myclass
}
// now 'myclass'is Disposed
在C# 8.0中,你可以写如下语句:
using var myclass=new MyClass();
而 "myclass" 将在作用域结束时自动释放。
using
语句的优点(与显式调用 Dispose()
相比)是无论您如何退出此块,都将调用 Dispose()
:通过运行到结尾、遇到 return
语句或抛出异常。
如果您在using
语句中实例化对象,则在代码退出using
块时,将自动调用Dispose()方法。
using(var myObject = new MyDisposableObject())
{
blah();
} // Dispose() is called here (or whenever the code exits the block)
如果你不使用 using
,那么显式调用 Dispose() 就由你(调用代码)来处理对象的释放。IDisposable
接口并在析构函数(finalizer)中调用Dispose
方法。class Foo : IDisposable
{
private bool m_disposed = false;
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
~Foo()
{
Dispose(false);
}
protected void Dispose(bool disposing)
{
if (!m_disposed)
{
if (disposing)
{
//release managed resources
}
//release unmanaged resources
m_disposed = true;
}
}
}
m_
前缀? - Kyle Delaneym_
作为私有成员的前缀...现在我使用 _
作为前缀。m
代表 member
(成员)。 - Cheng Chen