简体   繁体   中英

Extension method to Dispose List not working

I've written a simple extension method to dispose off all the items in a list:

public static void Dispose(this List<IDisposable> list) {
    for (int i = 0, il = list.Count; i < il; i++) {
        list[i].Dispose();
    }
    list.Clear();
}

But when I try to use it, the VS IntelliSense doesn't list it in the drop down, and cannot find the method at compile time. How do I make it work?

List<Bitmap> bitmaps = new List<Bitmap>();
bitmaps.Dispose(); // Error: List<Bitmap> does not contain a definition for Dispose()

Try this:

public static void Dispose<T>(this List<T> list) where T : IDisposable {
    for (int i = 0, il = list.Count; i < il; i++) {
        list[i].Dispose();
    }
    list.Clear();
}

Quick explanation: A List<Bitmap> is a List Of Bitmaps, not a List Of IDisposables even though Bitmap itself is an IDisposable. A List Of Bitmaps however is a List Of T or more exactly: a List Of T where T implements IDisposable. So the compiler happily accepts above extension method.

Further (just because this makes for such a nice example):

List<T> is said to be invariant with regards to its type parameter. Hence the following assignment is not allowed and will produce a compiler error:

List<IDisposable> l = new List<Bitmap>();

and neither is the following type conversion:

List<Bitmap> lb = new List<Bitmap>();
List<IDisposable> ld = (List<IDisposable>)lb;

If you are on .NET 4 however (where variance of type parameters was introduced) and you use a generic type with a covariant type parameter (such as IEnumerable<out T> ) the following type conversion becomes valid:

List<Bitmap> lb = new List<Bitmap>();
IEnumerable<IDisposable> ld = lb;

and is indeed done implicitly for you. In this case, the following extension method works too:

// In a static class:
public static void Dispose(this IEnumerable<IDisposable> e) {
    foreach(var x in e) {
        x.Dispose();
    }
}

// Somewhere else:
List<Bitmap> l = new List<Bitmap>();
l.Dispose();

List<Bitmap>不是List<IDisposable>尝试:

public static void Dispose<T>(this List<T> list) where T : IDisposable

您必须将List<Bitmap> List<IDisposable>List<IDisposable>才能使用此扩展方法。

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM