Dispose List的扩展方法不起作用

时间:2013-02-26 06:43:08

标签: c# oop extension-methods dispose idisposable

我写了一个简单的扩展方法来处理列表中的所有项目:

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

但是当我尝试使用它时,VS IntelliSense不会在下拉列表中列出它,并且在编译时找不到该方法。我如何使它工作?

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

3 个答案:

答案 0 :(得分:7)

试试这个:

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();
}

快速解释:List<Bitmap>是位图列表,而不是IDisposables列表,即使位图本身是IDisposable。然而,位图列表是T或更精确的列表:T的列表,其中T实现IDisposable。所以编译器很乐意接受上面的扩展方法。

进一步(因为这是一个很好的例子):

据说

List<T>在其类型参数方面是不变的。因此,不允许以下赋值,并将产生编译器错误:

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

并且以下类型转换都不是:

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

如果您使用的是.NET 4(其中引入了类型参数的方差)并且您使用具有协变类型参数的泛型类型(例如IEnumerable<out T>),则以下类型转换变为有效:

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

确实是为你隐式完成的。在这种情况下,以下扩展方法也适用:

// 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();

答案 1 :(得分:3)

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

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

答案 2 :(得分:-2)

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