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と同じインスタンスのいくつかを含むItemList.CreateSubSet(2)の 2 番目のインスタンスが与えられます。では、 のいずれかのインスタンスを呼び出すにはどうすればよいのでしょうか。ItemListItemDispose()ItemList

Itemを破棄する責任を負わないようにすることを検討しましたが、それでものインスタンスの 1 つ_groupを呼び出すと、他の ItemList を構成するオブジェクトの一部を破棄することになります。Dispose()ItemListItem

内で何らかの参照カウントを行う必要があり、参照Itemが1つしか残っていない場合にのみ破棄する必要がありますか? これに関連して、オブジェクトがサブセットであることがわかっている場合は、ItemList呼び出す前にオブジェクトを空にしますか? Dispose()または、ItemSubsetList同じであるItemListが使い捨てではないクラスを作成しますか? ItemSubsetListが のスコープをエスケープした場合、ItemListどのようにクリーンアップしますか?

設計パターンやガイダンスはありますか?

4

1 に答える 1

1

オブジェクトは変更可能か不変か、およびそれらに関連するコストはいくらか?

一般に、変更可能なオブジェクトには、リソースを保持しているかどうかに関係なく、常に 1 人の明確に認識できる所有者が必要であることをお勧めします。変更可能なオブジェクトへの参照が多数存在することは完全に許容されますが、IList<T>所有する への参照を保持するエンティティと、IList<T>他の誰かが所有する への参照を保持するエンティティとの間には明確な区別が必要です (後者は、エンティティは、たとえば、所有者の利益のために一部のデータをエンティティにコピーできるように、参照を与えられている可能性があります)。

あなたのようなシナリオでオブジェクトの所有権が問題になると私が予想する唯一のIDisposable場合は、オブジェクト自体が破棄可能であることを除いて不変である場合です (つまり、オブジェクトの状態が変更される唯一の方法は、破棄されたときです)。そのような状況が当てはまる場合、(1)コストが何であるかを知っており、それらが許容できること、および(2)を確認できる場合、あなたの状況は処分せずにアイテムを放棄することが合理的である可能性がある非常に数少ない状況の1つであると思います.のディクショナリWeakReferenceまたは類似の構造を使用して、ファイナライズの資格があるとまだ認識されていないインスタンスをリサイクルします。このようなアプローチはきれいとは言えませんが、場合によっては最善の方法です。

于 2013-01-26T22:12:23.240 に答える