c# - 为什么这些对象没有被处理掉

标签 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);
    }
}

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

最佳答案

foreach 不调用 Dispose 方法,只有 using 调用。 using 指令只是一个糖:

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

考虑 Dispose Pattern来自 MSDN 以更好地理解 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 CollectionDisposing . Disposing 用于释放应用程序中 .NET Framework 之外的非托管资源。 垃圾收集 是自动完成的,在您完全理解为什么需要它之前,您不应该强行执行它。

关于c# - 为什么这些对象没有被处理掉,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/29010182/

相关文章:

javascript - 根据 foreach 中的选择值显示 Div

c# - 为什么 Dispose() 应该处理托管资源而不是终结器?

c# - 行删除事件不会触发

c# - 用于集成测试的 stub 网络服务器

c++ - 异常安全的 for 循环

java - 列表 foreach 方法

c# - 如何处理我们没有引用的一次性元素?

c# - 拥有终结器的开销 - 在 Dispose 中有/没有 SuppressFinalize

c# - 顶级请求上的 ConfigureAwait(false)

c# - AspNetUsers' ID 作为单独表中的外键,一对一关系