Best way to dispose a list

2019-01-22 18:21发布

I am having List object. How can I dispose of the list?

For example,

List<User> usersCollection =new List<User>();

User user1 = new User();
User user2 = new User()

userCollection.Add(user1);
userCollection.Add(user2);

If I set userCollection = null; what will happen?

foreach(User user in userCollection)
{
    user = null;
}

Which one is best?

16条回答
ら.Afraid
2楼-- · 2019-01-22 18:44

Another idea for this post... If you were wanting to ensure that all members of a collection are properly disposed, you could use the following extension method:

public static void DisposeAll(this IEnumerable set) {
    foreach (Object obj in set) {
        IDisposable disp = obj as IDisposable;
        if (disp != null) { disp.Dispose(); }
    }
}

This looks through the collection for any member that implements IDisposableand disposing of it. From your executing code, you could clean up the list like this:

usersCollection.DisposeAll();
usersCollection.Clear();

This will ensure that all members get the chance to release resources and the resulting list is empty.

查看更多
贼婆χ
3楼-- · 2019-01-22 18:44

Best way is

userCollection= null;

Than GC will take care of rest.

查看更多
劳资没心,怎么记你
4楼-- · 2019-01-22 18:45

I don't agree that you shouldn't do anything if you don't need the objects in the list anymore. If the objects implement the interface System.IDisposable then the designer of the object thought that the object holds scarce resources.

If you don't need the object anymore and just assign null to the object, then these scarce resources are not freed until the garbage collector finalizes the object. In the mean time you can't use this resource for something else.

Example: Consider you create a bitmap from a file, and decide you don't need neither the bitmap, nor the file anymore. Code could look like follows:

using System.Drawing;
Bitmap bmp = new Bitmap(fileName);
... // do something with bmp until not needed anymore
bmp = null;
File.Delete(fileName); // EXCEPTION, filename is still accessed by bmp.

The good method would be:

bmp.Dispose();
bmp = null;
File.Delete(fileName);

The same accounts for objects in a list, or any collection. All objects in the collection that are IDisposable should be disposed. Code should be like:

private void EmptySequence (IEnumerable sequence)
{   // throws away all elements in the sequence, if needed disposes them
    foreach (object o in sequence)
    {
        System.IDisposable disposableObject = o as System.IDisposable;
        o = null;
        if (disposableObject != null)
        {
            disposableObject.Dispose();
        }
    }
}

Or if you want to create an IEnumerable extension function

public static void DisposeSequence<T>(this IEnumerable<T> source)
{
    foreach (IDisposable disposableObject in source.OfType(System.IDisposable))
    {
        disposableObject.Dispose();
    };
}

All lists / dictionaries / read only lists / collections / etc can use these methods, because they all implement IEnumerable interface. You can even use it if not all items in the sequence implement System.IDisposable.

查看更多
Fickle 薄情
5楼-- · 2019-01-22 18:46

As everyone has mentioned leave to GC, its the best option and don't force the GC. Setting the variable to null will mark the variable for the GC.

if your after more info: Best Practice for Forcing Garbage Collection in C#

查看更多
三岁会撩人
6楼-- · 2019-01-22 18:47

Yet another example of an extension method you can use to dispose a list of objects which implement the IDisposable interface. This one uses LINQ syntax.

    public static void Dispose(this IEnumerable collection)
    {
        foreach (var obj in collection.OfType<IDisposable>())
        {
            obj.Dispose();
        }
    }
查看更多
Explosion°爆炸
7楼-- · 2019-01-22 18:49

If your item in list is un-managed object then you can call Dispose() on every object by iterating it.

foreach(User user in userCollection)
{
user.Dispose();
}

If the list object is managed object then you need not do anything. GC will take care.

查看更多
登录 后发表回答