Dispose Before Scope

ID

csharp.dispose_before_scope

Severity

high

Remediation Complexity

trivial

Remediation Risk

low

Remediation Effort

low

Resource

Reliability

Language

CSharp

Tags

CWE:772, idisposable, reliability, resource-leak

Description

Reports local IDisposable variables that exit their enclosing method without a matching Dispose() call. Leaking an unmanaged resource (file handles, sockets, database connections) keeps it allocated until the finaliser runs, which on hot paths is enough to exhaust the process handle table.

Rationale

The IDisposable contract is the .NET runtime’s only deterministic mechanism for releasing native resources. Forgetting to call Dispose() defers the cleanup to the GC, which may take seconds or minutes; under load, the leak is fast enough to break the program before the GC notices.

public class Reader
{
    public string Bad(string path)
    {
        var stream = new FileStream(path, FileMode.Open);          // FLAW
        return new StreamReader(stream).ReadToEnd();
    }

    public string OkUsing(string path)
    {
        using (var stream = new FileStream(path, FileMode.Open))   // OK
        {
            return new StreamReader(stream).ReadToEnd();
        }
    }

    public string OkUsingDecl(string path)
    {
        using var stream = new FileStream(path, FileMode.Open);    // OK
        return new StreamReader(stream).ReadToEnd();
    }

    public string OkManual(string path)
    {
        var stream = new FileStream(path, FileMode.Open);          // OK, explicit Dispose
        try   { return new StreamReader(stream).ReadToEnd(); }
        finally { stream.Dispose(); }
    }
}

Remediation

Wrap the declaration in a using statement or the using var declaration form so the compiler emits the matching Dispose() call. When the disposable must outlive the method, transfer ownership explicitly (assign to a field, return it, or pass it to a registry that documents disposal responsibility).