好吧,我正在尝试了解可以通过代码显式完成的内存释放过程。
我在下面的 MS 线程中看到 Dispose 方法是在 Component 类中实现的。这里我有三个疑惑。
Component 类派生自 IDisposable,但是,在这个类库中,我发现它没有实现 Dispose 方法,甚至看起来也不是“public void Dispose() { }”。但是当我只写一个类并声明一个没有任何主体的方法时,它给我编译时错误说,我应该定义主体或使它抽象。为什么会有这种差异?
我一般都是这样用的,比如说“connection.Dispose();”在 finally block 中处理 sqlconnection。据我了解,SqlConnection 派生自 DBConnection,后者又派生自 Component。当我查看 Component 类时,我只看到方法“public void Dispose();”的声明。那么具体实现在哪里呢?
我还看到了一些专门实现的代码,例如下面 MS 网站中给出的代码。他们为 Dispose 状态声明了一个 bool 变量,并有一个新的 Dispose 方法,他们在该方法中调用对象上的组件 Dispose。他们还对非托管资源使用 Kernel32 方法 CloseHandle。这个方法有什么用?在处理它时,我从未将它用于我的 SqlConnection(这也是一种非托管资源)。
http://msdn.microsoft.com/en-us/library/system.gc.suppressfinalize(v=vs.110).aspx
有人能帮我简单地理解一下上面的三个问题吗?我只是在学习所有这些。谢谢
最佳答案
首先:
public void Dispose() { }
有一个 body ——它只是一个空的 body 。这里没有区别。实际上,尽管 Component.Dispose
是:
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
这个想法是,如果您想添加逻辑,您可以覆盖
protected virtual void Dispose(bool disposing)
方法。
其次,如果您像那样调用 connection.Dispose()
,那么您就做错了。您应该使用 using
block :
using(var conn = ...)
{
conn.Open();
using(var cmd = conn.CreateCommand())
{
// etc etc
}
// look ma, no finally
}
您的第三点以及您引用的 MSDN 文章只是您可能实际需要执行此操作的示例。 CloseHandle
方法只是一个非托管资源 的示例。这很关键,因为您不使用终结器来清理托管资源 - 只有未管理的资源。因此,涉及非托管句柄的示例只是一个说明的借口:
- 从终结器调用
Dispose(false)
覆盖
Dispose(bool)
方法- 让一些代码(句柄)从终结器和处置器中清除(分别为
Dispose(false)
和Dispose(true)
) - 有一些代码只在
Dispose(true)
情况下执行 - 即向前处置
关于c# - Component类库中实现的Dispose方法在哪里,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/19894454/