为什么这些物品没有被处理掉

时间:2015-03-12 12:47:19

标签: c# foreach idisposable

我的理解是,如果在foreach循环中调用实现IDisposable模式的对象,则它会自动处理,而无需在使用或调用Dispose方法中明确使用它。我有以下代码

class Program
{
    static void Main(string[] args)
    {
        using (Employee e = new Employee() { Name = "John" }) ;
        {

        }

        foreach (var e in GetEmployees())
            Console.WriteLine(e.Name);
    }

    static List<Employee> GetEmployees()
    {
        Employee emp = new Employee() { Name = "Peter" };
        Employee emp2 = new Employee() { Name = "Smith" };
        List<Employee> emps = new List<Employee>();
        emps.Add(emp);
        emps.Add(emp2);
        return emps;
    }
}

class Employee : IDisposable
{
    public string Name { get; set; }

    public void Dispose()
    {
        Console.WriteLine("disposing " + Name);
    }
}

我没有看到Dispose方法返回的对象调用GetEmployees。这是否意味着我需要在foreach循环中调用Dispose

2 个答案:

答案 0 :(得分:4)

foreach不会调用Dispose方法,只会调用usingusing指令只是一个糖:

try {
    // Initialize
}
finally {
    // Dispose
}

是的,你必须自己写Dispose电话,如下:

foreach (var e in GetEmployees())
{
    Console.WriteLine(e.Name);
    e.Dispose();
}

foreach (var e in GetEmployees())
{
    using (e)
    {
        Console.WriteLine(e.Name);
    }
}

考虑来自MSDN的Dispose Pattern,以便更好地理解Disposing在.NET中的工作方式:

简单用例

public class DisposableResourceHolder : IDisposable {

    private SafeHandle resource; // handle to a resource

    public DisposableResourceHolder(){
        this.resource = ... // allocates the resource
    }

    public void Dispose(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing){
        if (disposing){
            if (resource!= null) resource.Dispose();
        }
    }
}

具有可终结类型的复杂用例:

public class ComplexResourceHolder : IDisposable {

    private IntPtr buffer; // unmanaged memory buffer
    private SafeHandle resource; // disposable handle to a resource

    public ComplexResourceHolder(){
        this.buffer = ... // allocates memory
        this.resource = ... // allocates the resource
    }

    protected virtual void Dispose(bool disposing){
            ReleaseBuffer(buffer); // release unmanaged memory
        if (disposing){ // release other disposable objects
            if (resource!= null) resource.Dispose();
        }
    }

    ~ ComplexResourceHolder(){
        Dispose(false);
    }

    public void Dispose(){
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

更新:正如在评论中指出的那样,我认为您正在混淆Garbage CollectionDisposingDisposing用于释放应用程序中.NET Framework外部的非托管资源。 Garbage Collection会自动完成,除非您完全理解为什么需要它,否则不要强迫它。

答案 1 :(得分:2)

您必须手动调用Dispose(),或使用using()语句