【发布时间】:2016-06-29 12:14:00
【问题描述】:
假设我有以下类:
class Foo : IDisposable
{
public void Dispose()
{
bar.Dispose();
}
private Bar bar = new Bar();
}
class Bar : IDisposable
{
public void Dispose()
{
baz.Dispose();
}
private SomeThirdPartyLibraryClass baz = new SomeThirdPartyLibraryClass();
}
这段代码在使用using 语句时效果很好:
using (Foo foo = new Foo())
{
// ...
}
// All resources should be disposed at this time
但是,如果由于某种原因该类的用户忘记使用using 语句,则永远不会释放资源。
根据 MSDN,我应该通过以下方式实现一次性模式:
class Foo : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing) {
// Free any managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
~Foo()
{
Dispose(false);
}
bool disposed = false;
private Bar bar = new Bar();
}
(Bar 也是如此)
但是我应该将bar.Dispose(); 和baz.Dispose(); 代码放在哪里?
应该在“托管清理”部分下还是在“非托管清理”部分下?
顾名思义,我不知道SomeThirdPartyLibraryClass的实现(而且反正可以随时间改变)。
那我该怎么办?
【问题讨论】:
-
MSDN 上的哪个地方建议使用终结器作为通用 IDisposable 实现的一部分?
-
Is it possible to force the use of "using" for disposable classes? 可能重复,因为您无法修改第三方库。它还包含一些包装解决方案。
-
所有 .NET 对象都是托管的。它属于“在此处释放任何托管对象”。仅当您亲自合并非托管资源时(没有人有任何理由这样做,因为您可能想要使用的所有内容都已经包装在适合您的类中),任何事情都属于“免费的非托管资源”。第三方代码将处理 它 在其 自己的
Dispose(false)路径中分配的非托管资源。 -
@FrozenHeart 因为那篇文章建议实施终结器是可取的如果您有非托管资源,这不是常见的用例。有关更多信息,请参阅Dispose, Finalization, and Resource Management
标签: c# dispose unmanaged managed