很难用单词来描述这个问题,所以这是代码:
public class Item : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
_disposed = true;
if (disposing)
{
//dispose managed resources
if (_group != null) _group.Dispose();
_stream.Close(); //or some legitimate thing that needs cleaned up
}
//dispose unmanaged resources
}
ItemList _group;
public ItemList Group { get{return _group;} set{_group = value;}}
public int SomeValue {get; set;}
}
public class ItemList : IList<Item>, IDisposable
{
public ItemList(IList<Item> list) : base(list)
{
list.ForEach(i => i.Group = this);
}
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
private bool _disposed;
protected virtual void Dispose(bool disposing)
{
if (_disposed) return;
_disposed = true;
if (disposing)
{
//dispose managed resources
this.ForEach(i => i.Dispose());
}
//dispose unmanaged resources
}
public ItemList CreateSubSet(int value)
{
return new ItemList(this.Where(i => i.SomeValue == value));
}
}
因此,如果您以
ItemList
开头并调用ItemList.CreateSubSet(2)
,您将获得ItemList
的第二个实例,其中包含与原始ItemList中的某些相同的Item
实例。那么,如何在Dispose()
的任何一个实例上调用ItemList
,因为一旦这样做,您实际上将把它们全部处置掉?我已经考虑过让
Item
不负责处置_group
,但是即使这样,即使您在Dispose()
的一个实例上调用ItemList
,最终还是要处置一些构成Item
的对象。另一个ItemList。您是否必须在
Item
中进行某种引用计数,并且仅在仅剩1个引用时才进行处理?与此相关,如果您知道ItemList
是一个子集,也许在调用Dispose()
之前先清空ItemSubsetList
对象?还是创建与ItemList
相同但不是一次性的ItemSubsetList
类?如果ItemList
逃脱的范围怎么办,您将如何清理呢?任何设计模式或指导?
最佳答案
这些对象是可变的还是不可变的,与它们相关的成本是多少?
通常,我建议可变对象在任何给定时间几乎都应始终具有一个清晰可辨的所有者,无论它们是否拥有任何资源。对于一个可变对象存在许多引用是完全可以接受的,但是在拥有引用其拥有的IList<T>
的实体与拥有对其拥有的IList<T>
的引用的实体之间应该有明显的区别。由其他人(可能为后者提供了引用,以便可以为所有者的利益将一些数据复制到其中)。
我唯一希望IDisposable
对象的所有权在像您这样的情况下会出现问题,除非对象本身是不可变的(除了可以丢弃之外)(这意味着它们状态的唯一改变是在处理它们时)。如果适用这种情况,我认为您的情况是很少的一种情况,在这种情况下,如果可以确保(1)您知道成本是什么并且可以接受,并且(2)您可以使用WeakReference
字典或类似的结构来回收尚未被确认具有终结能力的实例。这样的方法很难看,但是在某些情况下可能是最好的。
关于c# - 当列表的子集存在时,如何管理IList对象的处置?,我们在Stack Overflow上找到一个类似的问题:https://stackoverflow.com/questions/14530489/