开发者

Should I have methods which return lists of Disposable instances?

开发者 https://www.devze.com 2022-12-18 16:17 出处:网络
I have a class, instances of which need to be disposed.I also have several classes that produce these instances, either singly or lists of them.

I have a class, instances of which need to be disposed. I also have several classes that produce these instances, either singly or lists of them.

Should I return IList<MyClass> from my methods or should I create a class that is MyClassCollection which is also disposable and return this instead?

EDIT:

My main reason for asking is that I have ended up doing this quite a lot:

IList<MyObject> list = GetList();
foreach(MyObject obj in list)
{
     //do something
     obj.Dispose();
} 

and it seems that I would be better doing:

using (IList<MyObject> list = GetList())
{
     foreach(MyObject obj in list)
     {
     //d开发者_如何学编程o something

     } 
}


It may be easier to generate a sequence of items (IEnumerable<T>) rather than a list - there are ways that you can make the lifetime of each tied into the iterator, so that:

  • you only have one at a time (I assume they are expensive)
  • they get disposed when their time is up
  • they all get disposed, even in error

This is a topic that I explored here using LINQ, but there are other ways too, if your source is (or can be) a sequence.


It depends on how you will use them, both seem reasonable options. If you know that you will need to dispose all the objects at the same time, then perhaps making the list disposable makes sense, but if the objects could have different lifetimes, I would just return an ordinary list.

Perhaps you could make a generic IDisposableList<T> with a constraint on T where T : IDisposable and have your class implement IDisposable by calling Dispose on all its elements? Then you can reuse this class for all your different IDisposable types.


It is completely up to the client code to call your Dispose() method. Only it knows when it is done using the objects. You cannot help in any way because you don't know what that code will look like. Creating list objects that dispose their elements is not a good idea. The framework contains no collection object that does this. You'll just confuse the client code programmer.


A container class would probably be cleaner in these instances. You can then continue using the standard collection classes, and you are forced to be more explicit about when the items will need disposing at the end.

public class ListScope : IDisposable
{
    private IList list;
    public ListScope(IList list)
    {
        this.list = list;
    }

    #region IDisposable Members

    public void Dispose ()
    {
        foreach ( object o in this.list )
        {
            IDisposable disposable = ( o as IDisposable );
            if (disposable != null)
                    disposable.Dispose ();
        }
    }

    #endregion
}

You could use as :

using ( new ListScope ( list ) )
{
   // Do stuff with list
}


You could also use an Extension if you wanted :

static class Extensions
{
 public static void DoStuffAndDisposeElements<T> ( this List<T> list, Action<T> action )
 {
        list.ForEach ( x => { action ( x );
               IDisposable disposable = (x as IDisposable);
               if ( disposable != null )
                  disposable.Dispose ();

        } );
 }


}

which you could call by :

getList().DoStuffAndDisposeElements ( x => doStuff(x));

Not sure how much you would gain from it, but there may be situations where it would be useful ;)

0

精彩评论

暂无评论...
验证码 换一张
取 消

关注公众号