[emoji848]
Legend
- Joined
- Dec 3, 2011
- Messages
- 2,225
- Reaction score
- 1,521
As I was showing a few friends a code snippet of a funny using chain, I found out how many C# programmers never understood the using() keyword in C#. So I thought maybe a little tutorial would do nicely?
The problem (Why IDisposable?)
To understand using() we need to understand the purpose of the IDisposable interface in C# first.
What people tried in managed languages like Java or C# was taking the memory management away from the programmer. Working with pointers / doing allocations directly and scr*wing up with the needed cleanup / handling at all proved to be a big issue. App crashes everywhere because of that.
They came up with the Garbage Collector, who from now one takes care of cleanups of allocated memory (= when you use new() you usually allocate).
Having the GC (Garbage Collector) they felt that Destructors were not so important anymore as they were mostly used for memory cleanups when an object reached the end of it's lifetime. Even though they still "kept" them, they work in a very weird way and you basically rely on the GC to call them whenever it feels like it, without having any control over it. So better stay away from these in C#.
This caused new issues for the programmers. We cannot detect if an object reaches the end of it's lifetime anymore. And we cannot react directly to that.
There are some cases left where Destructors did something other than just cleaning memory up. Things like:
The IDisposable interface
So C# came up with an Interface called "IDisposable" that can be implemented / inherit from any class that needs to to additional cleanups / handling of an objects disposal. The interface defines the abstract ".Dispose()" method that is supposed to be something like a destructor.
IDisposable has nothing to do with memory management (inside the C# application) or Garbage Collection! It is NOT done by the CLR (Common Language Runtime) automatically! No, you cannot skip it!
I highlighted this because I had someone ask me exactly this: "Huh? Why do I even need this? C# has Garbage Collection". That's the downside of it. It is the programmers / YOUR duty to call IDisposable.Dispose() once the Disposable object is no long in use!
Examples
Here are 3 examples of .NET classes that implement the IDisposable interface together with the reason why they do it. This might help you understand the purpose:
The FileStream class
The class System.IO.FileStream implements the IDisposable interface. It needs .Dispose() to be called in order to close the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
Know the explorer message: "Cannot access the file because it is used by another process" ? That's why you need to call .Dispose here
The SqlConnection class
The class System.Data.SqlClient.SqlConnection is a Component and as such has a .Dispose method. It will most likely close the connection to the SQL Server on dispose.
The Font class
The class System.Drawing.Font is disposable as well because it needs to release GDI (graphics device interface) resources associated with the Font.
The using keyword
What are we? Programmers. What do we do? Forget things.
:
Having the issue that you need to call .Dispose() .Close() or whatever method that is intended to clean an object up, C# came up with the using keyword.
This is both, nice to read and very useful when dealing with disposable objects.
Here is a simple example:
See no .Dispose() call? That's right! using() will wait until the execution of the code within its body has finished (in any way) and then calls .Dispose() on the used object!
Awesome, isn't it?
It get's even better:
In both of these cases the closing bracket ("}") is not reached when the data was read improperly. However the .Dispose() method of the used disposable object will still be called!
This lets you return / throw / do whatever you want inside the using scope and you can be sure that .Dispose() will still be called!
So when you can use using(), DO IT!
In some cases it will get a little funny...
But this is likely never the case
:
I hope this helps Beginners / Intermediates / w/e understand the using() and IDisposable a little better
The problem (Why IDisposable?)
To understand using() we need to understand the purpose of the IDisposable interface in C# first.
What people tried in managed languages like Java or C# was taking the memory management away from the programmer. Working with pointers / doing allocations directly and scr*wing up with the needed cleanup / handling at all proved to be a big issue. App crashes everywhere because of that.
They came up with the Garbage Collector, who from now one takes care of cleanups of allocated memory (= when you use new() you usually allocate).
Having the GC (Garbage Collector) they felt that Destructors were not so important anymore as they were mostly used for memory cleanups when an object reached the end of it's lifetime. Even though they still "kept" them, they work in a very weird way and you basically rely on the GC to call them whenever it feels like it, without having any control over it. So better stay away from these in C#.
This caused new issues for the programmers. We cannot detect if an object reaches the end of it's lifetime anymore. And we cannot react directly to that.
There are some cases left where Destructors did something other than just cleaning memory up. Things like:
- Closing a connection to a webserver
- Closing a connection to an SQL server
- Closing any other type of connection
- Releasing externally used resources (GPU memory, Windows shared memory)
- Closing a file handle
The IDisposable interface
So C# came up with an Interface called "IDisposable" that can be implemented / inherit from any class that needs to to additional cleanups / handling of an objects disposal. The interface defines the abstract ".Dispose()" method that is supposed to be something like a destructor.
IDisposable has nothing to do with memory management (inside the C# application) or Garbage Collection! It is NOT done by the CLR (Common Language Runtime) automatically! No, you cannot skip it!
I highlighted this because I had someone ask me exactly this: "Huh? Why do I even need this? C# has Garbage Collection". That's the downside of it. It is the programmers / YOUR duty to call IDisposable.Dispose() once the Disposable object is no long in use!
Examples
Here are 3 examples of .NET classes that implement the IDisposable interface together with the reason why they do it. This might help you understand the purpose:
The FileStream class
The class System.IO.FileStream implements the IDisposable interface. It needs .Dispose() to be called in order to close the current stream and releases any resources (such as sockets and file handles) associated with the current stream.
Know the explorer message: "Cannot access the file because it is used by another process" ? That's why you need to call .Dispose here

The SqlConnection class
The class System.Data.SqlClient.SqlConnection is a Component and as such has a .Dispose method. It will most likely close the connection to the SQL Server on dispose.
The Font class
The class System.Drawing.Font is disposable as well because it needs to release GDI (graphics device interface) resources associated with the Font.
The using keyword
What are we? Programmers. What do we do? Forget things.

Having the issue that you need to call .Dispose() .Close() or whatever method that is intended to clean an object up, C# came up with the using keyword.
This is both, nice to read and very useful when dealing with disposable objects.
Here is a simple example:
Code:
[COLOR="#0000FF"]using ([/COLOR]FileStream fs = new FileStream("C:\\Users\\Me\\Desktop\\test.txt", FileMode.Create)[COLOR="#0000FF"])
{[/COLOR]
byte[] data = new UTF8Encoding(true).GetBytes("Hello");
fs.Write(data, 0, data.Length);
[COLOR="#0000FF"]}[/COLOR]
See no .Dispose() call? That's right! using() will wait until the execution of the code within its body has finished (in any way) and then calls .Dispose() on the used object!
Awesome, isn't it?
It get's even better:
Code:
[COLOR="#0000FF"]using ([/COLOR]FileStream fs = new FileStream("C:\\Users\\Me\\Desktop\\test.txt", FileMode.Create)[COLOR="#0000FF"])
{[/COLOR]
byte[] data = new UTF8Encoding(true).GetBytes("Hello");
if (fs.Write(data, 0, data.Length) != data.Length)
[B][COLOR="#FF0000"] return false;[/COLOR][/B]
DoSometingElse();
[COLOR="#0000FF"]}[/COLOR]
Code:
[COLOR="#0000FF"]using ([/COLOR]FileStream fs = new FileStream("C:\\Users\\Me\\Desktop\\test.txt", FileMode.Create)[COLOR="#0000FF"])
{[/COLOR]
byte[] data = new UTF8Encoding(true).GetBytes("Hello");
if (fs.Write(data, 0, data.Length) != data.Length)
[B][COLOR="#FF0000"] throw new FileNotReadException("The file was not read correctly");[/COLOR][/B]
DoSometingElse();
[COLOR="#0000FF"]}[/COLOR]
In both of these cases the closing bracket ("}") is not reached when the data was read improperly. However the .Dispose() method of the used disposable object will still be called!
This lets you return / throw / do whatever you want inside the using scope and you can be sure that .Dispose() will still be called!
So when you can use using(), DO IT!
In some cases it will get a little funny...
Code:
using (SqlConnection conn = new SqlConnection(connStrBuilder.ConnectionString))
{
using (SqlCommand cmd = new SqlCommand("SELECT ItemNum, ItemName, SourceIndex FROM ti_Item", conn))
{
using (SqlDataReader reader = cmd.ExecuteReader())
{
while (reader.Read())
{
Item item = FetchItem(reader);
using (FileStream fs = new FileStream(UserSettings.File.ClientDatabaseFileName, FileMode.Create))
{
using (BinaryWriter bw = new BinaryWriter(fs))
{
bw.Write(item.x........);
}
}
}
}
}
}

I hope this helps Beginners / Intermediates / w/e understand the using() and IDisposable a little better

Last edited: