如何处理在foreach中设置的对象?

时间:2010-04-19 20:33:16

标签: idisposable

foreach(var someDisposableObject in listOfDisposableObjects)
{
    //some code
    someDisposableObject.Dispose(); //current code contains something like this.
}

是否有安全的方法,比如在这种情况下使用using子句?

对于我的第二次迭代(在获得响应之前),我将代码更改为

foreach(var someDisposableObject in listOfDisposableObjects)
{
    try
    {
        //some code
    }
    finally
    {
        someDisposableObject.Dispose(); //current code contains something like this.
    }
}

虽然

foreach(var someDisposableObject in listOfDisposableObjects)
{
    using( someDisposableObject )
    {
        //some code
    }
}

更整洁,更可能更安全。

3 个答案:

答案 0 :(得分:3)

我会说你的Dispose代码应该在这个foreach之外。

样本中未提及的关键点是如何生成一次性对象列表。如果在生成一次性对象列表时抛出异常会发生什么?您将需要处置目前已创建的那些。

理想情况下,您需要一个实现IDisposable的容器来容纳您的一次性对象。如果您的一次性对象实现IComponent,那么System.ComponentModel.Container就是您所需要的。如果没有,你可能需要自己动手。

代码可能类似于:

using(Container container = new Container())
{
    // Generate list and add each element to the container
    for (...)
    {
        someDisposableComponent = ...;
        container.Add(someDisposableComponent);
        listOfDisposableObjects.Add(someDisposableComponent);
    }

    ... 

    foreach(var someDisposableObject in listOfDisposableObjects)
    {
        ... some code ...
    }
}

如果您需要更多帮助,我建议您发布生成列表的代码。

答案 1 :(得分:2)

    foreach(var someDisposableObject in listOfDisposableObjects)
    {
        using (someDisposableObject)
        {
           //some code
        }
    }

答案 2 :(得分:1)

我认为这可能是你最好的选择:

try
{
    foreach(var someDisposableObject in listOfDisposableObjects) 
    { 
        //some code 
    } 
}
finally
{
    foreach(var someDisposableObject in listOfDisposableObjects) 
    { 
        someDisposableObject.Dispose();
    } 
}

编辑添加:

如果您无论如何都必须处理掉每一个物体,那么您可以这样做:

    private static void DoStuff(IEnumerable<IDisposable> listOfDisposableObjects)
    {
        using (var enumerator = listOfDisposableObjects.GetEnumerator())
        {
            if (enumerator.MoveNext())
                DoStuffCore(enumerator);
        }
    }

    private static void DoStuffCore(IEnumerator<IDisposable> enumerator)
    {
        using (var someDisposableObject = enumerator.Current)
        {
            if (enumerator.MoveNext())
                DoStuffCore(enumerator);

            // Do stuff with someDisposableObject                
        }
    }