假设我有一些对象C
,它包含对自身实例的引用,并且还实现了IDisposable
。如何处理对C
的其他实例的引用?我应该递归调用他们的dispose
方法,还是应该将它们设置为null?换句话说,首选哪种型号?
模型1:递归处置
public class C : IDisposable
{
public List<C> subItems = new List<C>();
public void Dispose()
{
foreach (C subItem in subItems)
subItem.Dispose();
// Dispose other stuff
}
}
模型2 :设置等于null
public class C : IDisposable
{
public List<C> subItems = new List<C>();
public void Dispose()
{
subItems = null;
// Dispose other stuff
}
}
答案 0 :(得分:8)
我应该递归调用他们的处理方法
是
但只有当C实际上需要IDisposable
时,这在您的代码中并不明显。它引用同一个类的实例的事实是不相关的,在所有拥有的IDisposable对象上调用Dispose()。
如果这是尝试帮助&#39;垃圾收集器,然后停止它,什么都不做。
答案 1 :(得分:-1)
我应该递归调用他们的处理方法
没有。如果你不需要它。 (GC清理它)
是。如果对象使用非托管资源。不处理非托管资源会导致内存泄漏。
答案 2 :(得分:-1)
这不仅是正确答案。
你要问ASK的主要问题是LIST真实的还是单个OWNER项目的主要问题吗?
如果是 - 唯一有效的行为 - 显式调用Dispose(如在第一个伪代码中)
如果项目是或可以共享,并且可以在另一个上下文而不是单个容器中使用(例如,与StreamWriter和Stream一起使用 - StreamWriter可以是&#34;所有者&#34; of Stream并关闭它,但是您可以使用keepLive参数来保持Stream打开)。在共享的情况下,唯一有效的方法是从这种情况运行 - 因为如果你处置 - 你可以打破其他任务,如果不处理,只是清除列表 - 你可以保留一些资源,没有任何机会清理。
在C ++中的shared_ptr或.NET中的常用引用中使用ninja方式共享的方式 - 跟踪使用计数 -
class C:IDisposable{
int usageCount = 0;
public void AddUsage(){usageCount++;};
public void Dispose(){
if(usageCount>0){
usageCount--;
return;
}
//ELSE DO REAL DISPOSE LOGIC
}
}
但希望不是你的情况)