324

What is the purpose of the Using block in C#? How is it different from a local variable?

John Smith
  • 7,243
  • 6
  • 49
  • 61
Ryan Michela
  • 8,284
  • 5
  • 33
  • 47

9 Answers9

391

If the type implements IDisposable, it automatically disposes that type.

Given:

public class SomeDisposableType : IDisposable
{
   ...implmentation details...
}

These are equivalent:

SomeDisposableType t = new SomeDisposableType();
try {
    OperateOnType(t);
}
finally {
    if (t != null) {
        ((IDisposable)t).Dispose();
    }
}
using (SomeDisposableType u = new SomeDisposableType()) {
    OperateOnType(u);
}

The second is easier to read and maintain.


Since C# 8 there is a new syntax for using that may make for more readable code:

using var x = new SomeDisposableType();

It doesn't have a { } block of its own and the scope of the using is from the point of declaration to the end of the block it is declared in. It means you can avoid stuff like:

string x = null;
using(var someReader = ...)
{
  x = someReader.Read();
}

And have this:

using var someReader = ...;
string x = someReader.Read();
Caius Jard
  • 72,509
  • 5
  • 49
  • 80
plinth
  • 48,267
  • 11
  • 78
  • 120
  • 25
    Note that in general the finally block will check for nullity before calling Dispose. Not that it matters when you're calling a constructor, but... – Jon Skeet Oct 17 '08 at 13:59
  • 4
    If you declare the variable outside the using block and then create a new instance in the using statement it may not dispose the item. – John Oct 17 '08 at 14:13
  • 3
    So the using statement will automatically dispose of the object once that context is complete, WHEN should we use the using statement then, on types that implement IDisposable? Which types must implement that interface, is there any sort of rule of thumb on this or do I have to check each type individually? – JsonStatham May 20 '15 at 13:47
  • 2
    Being pedantic you need curly braces around your second code block to reflect the limited scope. – Caltor Feb 25 '17 at 01:14
  • 1
    Suppose you're multithreading and the object's method containing the `using` block is called twice. If the first thread is stopped in the `using` block, will a second `SomeDisposableType` be created for the second thread? – Micteu May 03 '17 at 14:10
  • 7
    **Note:** watch out for using the `using` block with `HttpClient()`! See [this article](https://aspnetmonsters.com/2016/08/2016-08-27-httpclientwrong/). – jbyrd Aug 30 '17 at 00:29
  • what in case if a method does not implement IDisposable. Won't it be disposed? – Ankush Jain Sep 24 '17 at 07:41
  • 1
    If you have `using (your-type-without-IDisposable...)` you get an error: "'your-type-without-IDisposable': type used in a using statement must be implicitly convertible to 'System.IDisposable'" – plinth Sep 25 '17 at 15:47
130

Using calls Dispose() after the using-block is left, even if the code throws an exception.

So you usually use using for classes that require cleaning up after them, like IO.

So, this using block:

using (MyClass mine = new MyClass())
{
  mine.Action();
}

would do the same as:

MyClass mine = new MyClass();
try
{
  mine.Action();
}
finally
{
  if (mine != null)
    mine.Dispose();
}

Using using is way shorter and easier to read.

mattcan
  • 540
  • 12
  • 30
Sam
  • 28,421
  • 49
  • 167
  • 247
  • Is null check necessary ? How can mine be null after "new MyClass()"; The only thing i can see is a OutOfMemoryException but in that case it shouldn't even enter the try block right ? EDIT : you probably wrote this to show what is done usually when using is used. Inside the using, there might be something else than a new constructor call (eg : a method call that return null) – tigrou Nov 06 '18 at 17:38
  • 2
    well, you could do other things than `mine.Action()`. Things like `mine=null`. Without using mine can be set to anything in the try/catch – Sam Nov 07 '18 at 18:21
57

From MSDN:

C#, through the .NET Framework common language runtime (CLR), automatically releases the memory used to store objects that are no longer required. The release of memory is non-deterministic; memory is released whenever the CLR decides to perform garbage collection. However, it is usually best to release limited resources such as file handles and network connections as quickly as possible.

The using statement allows the programmer to specify when objects that use resources should release them. The object provided to the using statement must implement the IDisposable interface. This interface provides the Dispose method, which should release the object's resources.

In other words, the using statement tells .NET to release the object specified in the using block once it is no longer needed.

Robert S.
  • 25,266
  • 14
  • 84
  • 116
30

The using statement is used to work with an object in C# that implements the IDisposable interface.

The IDisposable interface has one public method called Dispose that is used to dispose of the object. When we use the using statement, we don't need to explicitly dispose of the object in the code, the using statement takes care of it.

using (SqlConnection conn = new SqlConnection())
{

}

When we use the above block, internally the code is generated like this:

SqlConnection conn = new SqlConnection() 
try
{

}
finally
{
    // calls the dispose method of the conn object
}

For more details read: Understanding the 'using' statement in C#.

Luke Willis
  • 8,429
  • 4
  • 46
  • 79
Sunquick
  • 301
  • 3
  • 4
11
using (B a = new B())
{
   DoSomethingWith(a);
}

is equivalent to

B a = new B();
try
{
  DoSomethingWith(a);
}
finally
{
   ((IDisposable)a).Dispose();
}
Bert Huijben
  • 19,525
  • 4
  • 57
  • 73
9

Also take note that the object instantiated via using is read-only within the using block. Refer to the official C# reference here.

5

Placing code in a using block ensures that the objects are disposed (though not necessarily collected) as soon as control leaves the block.

TheSmurf
  • 15,337
  • 3
  • 40
  • 48
3

The using statement obtains one or more resources, executes a statement, and then disposes of the resource.

3

It is really just some syntatic sugar that does not require you to explicity call Dispose on members that implement IDisposable.

SaaS Developer
  • 9,835
  • 7
  • 34
  • 45
  • Isn't that the best phrase ever? "syntactic sugar" I can't say that enough, right after I buy a bunch of sea shells by the seashore. – iGanja May 28 '20 at 23:52