C#
error-handling
programming
.NET
code-practices

'using' statement vs 'try finally'

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

Introduction

In C#, using and try/finally solve the same resource-management problem: they make sure cleanup happens even when the code exits early or throws an exception. The difference is that using is a specialized language feature for IDisposable objects, while try/finally is the more general control-flow tool that using effectively expands into.

What using really does

When you write a using block, the compiler generates logic that calls Dispose() in a finally block. That is why using is usually preferred for files, streams, database connections, and other disposable resources.

csharp
1using System;
2using System.IO;
3
4class Program
5{
6    static void Main()
7    {
8        using (var writer = new StreamWriter("log.txt"))
9        {
10            writer.WriteLine("hello");
11        }
12    }
13}

The cleanup is deterministic. As soon as execution leaves the block, Dispose() runs.

The equivalent try/finally form

The same logic can be written manually with try/finally.

csharp
1using System;
2using System.IO;
3
4class Program
5{
6    static void Main()
7    {
8        StreamWriter writer = new StreamWriter("log.txt");
9        try
10        {
11            writer.WriteLine("hello");
12        }
13        finally
14        {
15            writer.Dispose();
16        }
17    }
18}

This is more verbose, but it makes the relationship clear: using is the concise form for a common try/finally pattern.

Why using is usually the better choice

For straightforward disposal, using communicates intent immediately. A reader can see that the object is scoped to a block and will be cleaned up automatically. That reduces boilerplate and lowers the chance of forgetting to call Dispose().

Modern C# also supports using var, which shortens the syntax even further.

csharp
1using System;
2using System.IO;
3
4class Program
5{
6    static void Main()
7    {
8        using var writer = new StreamWriter("log.txt");
9        writer.WriteLine("hello");
10    }
11}

The object is disposed at the end of the enclosing scope.

When try/finally is still the right tool

try/finally is still useful when cleanup is not just Dispose(), when multiple pieces of cleanup must happen in a specific order, or when the resource lifetime does not match a neat lexical block.

For example, you may need to set a flag before a section of code and restore it afterward regardless of success or failure.

csharp
1bool oldValue = Console.CursorVisible;
2try
3{
4    Console.CursorVisible = false;
5    Console.WriteLine("Working...");
6}
7finally
8{
9    Console.CursorVisible = oldValue;
10}

That is not a using problem. It is general cleanup logic, which is exactly what finally is for.

using does not replace exception handling

Another common misunderstanding is treating using as an error-handling feature. It is not. using guarantees disposal, but it does not catch exceptions for you. If you need to handle an error and also dispose of a resource, combine using with try/catch.

That separation of responsibilities is useful:

  • 'using controls resource lifetime.'
  • 'catch handles errors.'
  • 'finally handles cleanup that is not naturally modeled as IDisposable.'

Choose based on the cleanup model

If you are disposing an IDisposable within a clear scope, use using. If you need broader, custom, or non-disposable cleanup logic, use try/finally. If both are true, combine them instead of forcing one construct to do the other's job.

That is the practical rule most teams follow.

Common Pitfalls

  • Writing manual try/finally disposal everywhere when a simple using block would be clearer.
  • Assuming using catches exceptions instead of only ensuring disposal.
  • Holding a disposable object longer than necessary by giving it a scope that is too wide.
  • Forgetting that try/finally is still needed for cleanup that is not based on IDisposable.
  • Disposing resources manually inside a using block and making the lifetime harder to reason about.

Summary

  • 'using is specialized syntax for deterministic disposal of IDisposable resources.'
  • It effectively compiles down to a try/finally cleanup pattern.
  • Use using for normal disposable resources such as streams and database connections.
  • Use try/finally for custom cleanup that is not just Dispose().
  • Combine using with catch when you need both disposal and explicit error handling.

Related reading
Course
Intermediate
27 lessons
14 hours
OOD Fundamentals

Master object-oriented design from first principles, SOLID, design patterns, and classic interview problems with hands-on coding.

View the course
Track what you have practised

A free account saves your progress, solutions and study plan across every problem on Codemia.

Interview Questions practice on Codemia

Over 8,000 real interview questions from top companies, searchable by company and role.

Browse interview questions

All Rights Reserved.