This article is an introduction to the C# using statement and explain why and how to use it. I’ll also describe features of using statement and examples of nested using.
In C#, every object is using some resources managed or unmanaged internally. Client is responsible for life cycle of the object. Life cycle of the object means creation or destroying the object. But when client destroying the object it doesn’t have the option of releasing the resources the object is currently holding. When client assigned null to an object, it is only removing reference of the object from the stack. Object is not removed from the heap. When garbage collection runs it removed the object from the memory. But garbage collector is non-deterministic. That means we don’t know when garbage collector runs and when object will be destroyed from the memory. Also garbage collector don’t know how to release unmanaged resources for e.g. if sql connection is open at the time of destroying object, then garbage collection doesn’t know how to close the connection. It simply removes the object from the heap.
C# provides an option to give client a way to release resource explicitly. For every object which is using some resources have to implement IDisposable interface. IDisposable has only one method Dispose. In the Dispose method, object has to write all the code to release resources. Now client has the option to release resources by calling this Dispose method. Below is the example of calling Dispose method.
class Program
{
static void Main(string[] args)
{
SqlHelper sqlHelper = new SqlHelper();
//use sqlHelper
//after use call Dispose() method to release resources
sqlHelper.Dispose();
}
}
public class SqlHelper : IDisposable
{
public void Dispose()
{
//release sql resources
}
}
Why to use C# using statement
C# provides a special “using” statement to call Dispose method explicitly. using statement gives you a proper way to call the Dispose method on the object.
In using statement, we instantiate an object in the statement. At the end of using statement block, it automatically calls the Dispose method.
using statement provides some unique features.
- Manage Scope: It also manages the scope of the object. At the end of using block, using calls the Dispose method and in the method, object release all its resources and should not be available further.
- Instantiate the object as read-only: Object instantiates in the using statement are read-only and you can not modify or reassigned the object. This feature ensures Dispose method is called on the object which is instantiated.
- Ensures Dispose method will always be called: using statement also ensures Dispose method will always be called whether any exception was occurred or not.
How to use C# using statement
Below is syntax for using statement:
using(SqlHelper sqlHelper = new SqlHelper())
{
// use sqlHelper object
} //automatically calls Dispose method
sqlHelper object is not available outside the using statement.
How using internal work
using statement convert your code block to try..finally block internally like shown below:
SqlHelper sqlHelper = new SqlHelper();
try
{
// use sqlHelper object
}
finally
{
if (sqlHelper != null)
{
((IDisposable)sqlHelper).Dispose();
}
}
C# compiler also checks the object which you are instantiate whether it is value type or reference type. If it is value type then in the finally block it will not put check condition for null checking.
Nested using
You can also used nested using statements. Below is the example:
using (Customer customer = new Customer())
{
using (Order order = customer.Order)
{
Console.WriteLine(order.ItemName);
}
}
Using Example
Below is the example of using SqlConnection and SqlCommand objects.
static void Main(string[] args)
{
string connString = "...";
using(SqlConnection sqlConnection = new SqlConnection(connString))
{
using(SqlCommand sqlCommand = sqlConnection.CreateCommand())
{
sqlCommand.CommandText = "SELECT * FROM Customer";
sqlConnection.Open();
using(SqlDataReader dataReader = sqlCommand.ExecuteReader(CommandBehavior.CloseConnection))
{
while(dataReader.Read())
{
//fill your object
}
}
}
}
}
Final words
Remember, you can only use object in using statment which implements the IDisposable interface. You should always use using statement whenever you have to release resources immediately.