2

很难用语言来描述这个问题,所以这里是代码:

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其中包含Item原始 ItemList 中的一些相同实例。那么你怎么去调用Dispose()任何一个实例ItemList,因为一旦你这样做了,你实际上会处理它们两个?

我考虑过让makeItem不负责处置_group,但即便如此,如果您调用Dispose()的一个实例ItemList,您最终还是会处置Item构成另一个 ItemList 的一些对象。

您是否必须在 内进行某种引用计数Item,并且仅在仅剩 1 个引用时才处理它?与此结合,如果您知道它是一个子集,也许ItemList在调用之前清空对象?Dispose()或者也许可以创建一个ItemSubsetList相同ItemList但不是一次性的课程?如果ItemSubsetList逃脱了 的范围ItemList,那么你将如何清理它?

任何设计模式或指导?

4

1 回答 1

1

对象是可变的还是不可变的,与它们相关的成本是多少?

一般来说,我建议可变对象在任何给定时间几乎总是有一个可清晰识别的所有者,无论它们是否拥有任何资源IList<T>存在对可变对象的许多引用是完全可以接受的,但是在一个持有对其拥有的对象的引用的实体和持有对其IList<T>他人拥有的对象的引用的实体之间应该有明显的区别(后者例如,实体可能已经获得了引用,以便它可以将一些数据复制到其中以获取所有者的利益)。

我唯一期望IDisposable对象的所有权在像您这样的情况下会出现问题的情况是,如果对象本身是不可变的,除了是一次性的(这意味着它们的状态可以改变的唯一方法是在它们被处置时)。如果这种情况适用,我认为您的情况是极少数情况之一,如果能确保(1)您知道成本是多少,并且它们是可以接受的,并且(2)您使用字典WeakReference或一些类似结构来回收尚未被识别为符合最终确定条件的实例。这种方法并不漂亮,但在某些情况下可能是最好的。

于 2013-01-26T22:12:23.240 回答