处理 IDisposable 的集合

Disposing of a collection of IDisposable

我有一个方法returns DirectoryEntry 对象的集合。

static IEnumerable<DirectoryEntry> Bar(){ ... }

当我完成收集并处理每个项目时,我一直在遍历该集合,但我想知道最佳做法是什么。

例如

var foo = Bar();
\ Do some work
foreach (var f in foo)
{
    f.Dispose();
}

差不多。您应该对从函数返回的 Dispose() 一次性对象负责,参见例如 here,可能在 finally 块中。

无法保证每次枚举 IEnumerable(即使用 foo.GetEnumerator()foreach)时都获得相同的 DirectoryEntry 对象集。你每次都可能得到新的,re-enumerating 可能会导致不必要的 IO。例如这个

    static int n = 0;
    static IEnumerable<int> Bar()
    {
        for (int i = 0; i < 10; i++)
        {
            yield return n++;
        }

    }

    
    static void Main(string[] args)
    {
        var foo = Bar();
        
        var count = foo.Count();
        foreach(var i in foo)
        {
            Console.WriteLine(i);
        }
        foreach (var i in foo)
        {
            Console.WriteLine(i);
        }

    }

将迭代 IEnumrable 三次,生成 30 个不同的 ints。

因此,您经常需要在 List 或其他 ICollection 中收集 IEnumerable。

var foo = Bar().ToList();
try
{
    // Do some work
}
finally
{
    foreach (var f in foo)
    {
        f.Dispose();
    }
}

像这样

foreach (var f in Bar())
{
    using (f)
    {
        //Do some work
    }
}

是有风险的,因为如果 Bar() returns 一个集合,并且你有一个异常,un-enumerated 对象将不会被释放。