C# Language Using Statement Using Statement Basics

Help us to keep this website almost Ad Free! It takes only 10 seconds of your time:
> Step 1: Go view our video on YouTube: EF Core Bulk Insert
> Step 2: And Like the video. BONUS: You can also share it!

Example

using is syntactic sugar that allows you to guarantee that a resource is cleaned up without needing an explicit try-finally block. This means your code will be much cleaner, and you won't leak non-managed resources.

Standard Dispose cleanup pattern, for objects that implement the IDisposable interface (which the FileStream's base class Stream does in .NET):

int Foo()
{
    var fileName = "file.txt";

    {
        FileStream disposable = null;

        try
        {
            disposable = File.Open(fileName, FileMode.Open);

            return disposable.ReadByte();
        }
        finally
        {
            // finally blocks are always run
            if (disposable != null) disposable.Dispose();
        }
    }
}

using simplifies your syntax by hiding the explicit try-finally:

int Foo()
{
    var fileName = "file.txt";

    using (var disposable = File.Open(fileName, FileMode.Open))
    {
        return disposable.ReadByte();
    }
    // disposable.Dispose is called even if we return earlier
}

Just like finally blocks always execute regardless of errors or returns, using always calls Dispose(), even in the event of an error:

int Foo()
{
    var fileName = "file.txt";

    using (var disposable = File.Open(fileName, FileMode.Open))
    {
        throw new InvalidOperationException();
    }
    // disposable.Dispose is called even if we throw an exception earlier
}

Note: Since Dispose is guaranteed to be called irrespective of the code flow, it's a good idea to make sure that Dispose never throws an exception when you implement IDisposable. Otherwise an actual exception would get overridden by the new exception resulting in a debugging nightmare.

Returning from using block

using ( var disposable = new DisposableItem() )
{
    return disposable.SomeProperty;
}

Because of the semantics of try..finally to which the using block translates, the return statement works as expected - the return value is evaluated before finally block is executed and the value disposed. The order of evaluation is as follows:

  1. Evaluate the try body
  2. Evaluate and cache the returned value
  3. Execute finally block
  4. Return the cached return value

However, you may not return the variable disposable itself, as it would contain invalid, disposed reference - see related example.



Got any C# Language Question?