可能重复:在Dispose()中设置obj = null(Nothing)的意义?
我理解这个问题是否重复,但我在调整一些关于这个主题的帖子时遇到了一些麻烦 .
首先是一点背景 . 我有一个类Foo如下
public class Foo : IDisposable
{
private Dictionary<int, string> _reallyBigDictionary =
new Dictionary<int, string>();
public void Dispose()
{
_reallyBigDictionary = null;
}
}
众所周知,Foo的实例范围有限(即我知道我们不会永远保留它) . 鉴于它的实例范围有限,我没有看到_reallyBigDictionary如何实际上比释放更快地释放内存 . 我理解它的方式,这些对象在运行垃圾收集之前不会被清除 . 那时,无论如何,对给定Foo实例的引用都将为null,因此我希望GC能够回收该内存 .
这些帖子让我相信将成员变量设置为null没有意义:
Memory leak problems: dispose or not to dispose managed resources?
Is it better to destroy all objects or just let the garbage collector do the job?
这篇文章让我质疑:Proper use of the IDisposable interface
任何人都可以为我澄清这一点吗? IDisposable实现在这里真的有必要吗?因为我无法说服自己 .
3 回答
你不需要
IDisposable
; here's why . 总之,您需要遵循规则1:除非您需要,否则不要实现IDisposable
.确实需要实施
IDisposable
时只有两种情况:该类拥有非托管资源 .
该类拥有托管(
IDisposable
)资源 .由于
Dictionary<int, string>
不是IDisposable
,所以你的 class 也不应该 .通过实现
IDisposable
接口,您可以使用Using
语句确定资源的使用范围 . 支持.NET Framework的许多类检测到一个类是IDisposable并为您运行Dispose()
,这使您免除了对托管子对象进行归零的责任 .EDIT ----
由于评论和降价,我认为我添加到我的答案:
.NET Framework中的许多类都实现了IDisposable - 例如许多Generic集合类型 . 处理这样的集合时,Microsoft实现将调用您的类的Dispose方法,检测到它实现了IDisposable . 此外,还有一种情况是将对象的引用设置为null(也可能在您的Dispose方法中) . 如果要删除对象的引用,请将引用设置为null . 其他类可能希望维护对同一对象的引用,因此将引用设置为null的参数是错误的'是一个有缺陷的参数 . 使用Dispose方法将引用设置为null与以任何其他方式将其设置为null没有区别 - 已授予,但通过在IDisposable实现中执行此操作,您可以采用更加确定且防错的方式来确保发生这种情况 . 实现IDisposable也是实现范围界定的一种很好的方法,例如,对于事务算法等,实现IDisposable在很多方面都是有用的,只要你知道它是如何工作的以及为什么工作的原因就不必避免 . 令我惊讶的是,很少有.NET开发人员真正理解IDisposable接口,Finalizer,垃圾收集器和.NET最佳实践
在这种情况下,我认为不需要处置 . 它不是一个活跃的连接,它会保持开放并继续消耗资源 . 当你完成它的使用后,它将自行管理 .
如果您确实希望确保该代码中没有内存泄漏,可以尝试将以下内容添加到dispose方法中: