为什么这些对象没有被处置

BKS*_*BKS 1 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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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

VMA*_*Atm 5

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

try {
    // Initialize
}
finally {
    // Dispose
}
Run Code Online (Sandbox Code Playgroud)

是的,你必须Dispose自己编写调用,如下所示:

foreach (var e in GetEmployees())
{
    Console.WriteLine(e.Name);
    e.Dispose();
}
Run Code Online (Sandbox Code Playgroud)

或者

foreach (var e in GetEmployees())
{
    using (e)
    {
        Console.WriteLine(e.Name);
    }
}
Run Code Online (Sandbox Code Playgroud)

考虑MSDN 中的Dispose 模式,以便更好地理解 .NET 中的工作方式Disposing

简单用例

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();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

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

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);
    }
}
Run Code Online (Sandbox Code Playgroud)

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