When we create objects in .NET we don’t need to explicitly release these objects after we have used them.This is because the garbage collector takes care of releasing the memory occupied by the object once that object goes out of scope.
This is really helpful because we are not required to explicitly delete the objects.Garbage collector takes care of releasing only the managed objects.This means that if our object is accessing some unmanaged resources then these resources will not be garbage collected by the garbage collector.
Since these resources are not automatically garbage collected like the other resources it is the responsibility of the programmer to release these resources .Framework provides IDisposable interface to release such unmanaged resources.This interface defines a single Dispose method ,the job of which is to release the unmanaged resources.
So if we are creating an object of SqlConnection class ,which is used for connecting to databases then we can call Dispose method on this object as:
SqlConnection conn = new SqlConnection(connString); conn.Open(); //use the conn object conn.Dispose();
Though the above code disposes the connection object yet it can fail when an exception occurs.To handle this situation we can use the exception handler.So we can use the following code to properly dispose the connection object even in the case of exceptions.
SqlConnection conn = new SqlConnection(connString); try { conn.Open(); } finally { conn.Close(); }
Using statement in C#
Since calling the Dispose method is such a common scenario ,so framework provides us with a short form for calling the Dispose method.
“using” statement in C# is a compact form of writing the Disposable object in a try finally block. .We can write the above code with “using” statement as:
using(SqlConnection conn = new SqlConnection(connString)) { //use the conn object }
We can generalise this syntax as:
using(create object of type implementing IDisposable)
{
//use the object
}
The object created in the using() goes out of scope once the using() block ends.So we can not access the object outside the using() block.
Following are the advantages of creating an object in a using statement:
- It provides a compact syntax for calling the Dispose method.
- While if call the Dispose method explicitly we can forget to call the method ,”using” statement ensures that the Dispose method is always called.
- It prevents accidentally accessing the disposed objects.
If create an object and call the Dispose method explicitly and then try to access that object we will exception.For example following is a valid statement:
SqlConnection connectionObj = new SqlConnection(); connectionObj.Dispose(); var state=connectionObj.State;
Though the above statement is valid but we will get exception at line number 3 since we are trying to access an object after calling the Dispose method.
If we create the object in a using statement then the scope of the object is limited to the using block so such errors will not occur.
Below we are creating SqlConnection object in a using statement.After the using block ends we are trying to access the same object.But we can not see it in the intellisense.This is because the scope of the object is limited to the using block so we are not allowed to access the object outside the block.