How it works
IDisposable describes a deterministic cleanup operation. A using statement arranges to call Dispose when control leaves its scope, including when an exception leaves the body. This is useful when an object owns a resource whose useful lifetime should end at a known point, rather than waiting for eventual garbage collection.
Ownership determines who should dispose an object. A method that creates a resource and does not transfer ownership is usually responsible for its cleanup. A method that merely borrows an object from a caller should not dispose it unless that is part of the contract. The syntax expresses the lifetime boundary; it does not decide the ownership policy on the programmer's behalf.
Walk through the example. The example uses a small in-memory Lease object whose disposal state is observable. Inside the using block, IsDisposed is false and the body prints working. When the block ends, using calls Dispose. The final observation is true. This deliberately simple model isolates the lifetime rule without opening a file, connecting to a service, or relying on a platform-specific native handle.
Watch the boundary. Disposing an object does not necessarily set every variable that refers to it to null, and the garbage collector has a different role from deterministic cleanup. The object can still be referenced after disposal, but its contract may prohibit further use. Also avoid disposing a shared dependency merely because it implements IDisposable; its owner may need it for work after your method returns.
Practice independently. Add a method to the Lease type that rejects use after disposal, and demonstrate a safe using scope around it. Then write a helper that borrows a lease and performs work without taking ownership. Show that the caller can still use it afterward until the caller's own scope ends. Finally explain why a long-lived shared resource needs a different owner from a short-lived per-operation resource.
A working example
using System;
using System.Collections.Generic;
using System.Linq;
using System.Globalization;
using System.Text;
using System.Text.Json;
using System.Text.Json.Serialization;
using System.Text.RegularExpressions;
var lease = new Lease();
using (lease)
{
Console.WriteLine(lease.IsDisposed);
Console.WriteLine("working");
}
Console.WriteLine(lease.IsDisposed);
sealed class Lease : IDisposable
{
public bool IsDisposed { get; private set; }
public void Dispose() => IsDisposed = true;
}
Expected output
False working True
The owner controls disposal; borrowing a disposable dependency does not imply owning it.