BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 1.1+

C# Using Statement

If an object is of a class that implements the IDisposable interface, you should dispose of the object as early as possible. You can dispose of an object manually with the Dispose method. The using statement provides a more elegant approach.

The Using Statement

In a previous article we have seen the use of the using directive. This command improves the formatting of code by specifying the namespaces that are used in a code file and allowing members of the namespace to be used without being fully qualified. It also permits the creation of namespace aliases. In this article we will examine the using statement. Although the keyword is the same, the use of the statement and directive are very different.

The using statement provides a simple, convenient syntax that ensures that objects that implement the IDisposable interface are correctly disposed. When instantiating classes that implement this interface, you should dispose of the object at the earliest opportunity, once you know that it is no longer required.

Without the using statement, you can call the object's Dispose method to indicate that you wish the object to clean up its resources. This usually means that you must create a try / catch / finally block around the use of the disposable object. The Dispose method will be called in the finally block to ensure that it is executed, even if an exception is thrown during processing. For example, the following code attempts to open a file stream. Whether this is successful or causes an exception, the stream will be disposed in the finally code block.

Stream stream = null;

try
{
    stream = File.OpenRead(@"c:\test\test.txt");

    // More code that uses the stream here
}
finally
{
    if (stream != null) stream.Dispose();
}

This syntax is acceptable but does have some problems. One of the key issues is that the Stream variable in the example is still within the scope of the method after the try / finally block. This leads to the possibility that it may accidentally be used again, even though it has been disposed. It would be better if the variable were inaccessible at this point. The syntax is also quite unwieldy, particularly if there is a lot of code within the try block.

The using statement removes both problems. Within the statement one or more variables of disposable types are declared. The using statement includes a code block and the declared variables exist only in the scope of this block. If the code within the statement is executed normally, or if an exception is thrown and the code block is left, the Dispose method for each of the variables is called automatically.

We can recreate the functionality of the previous sample code, this time with the using statement, as follows:

using (Stream stream = File.OpenRead(@"c:\test\test.txt"))
{
    // More code that uses the stream here
}

You can see that this version of the code is much simpler. However, this is essentially syntactic sugar as the compiler creates almost the same output for both examples. The only difference is that the version containing the using statement creates an additional containing code block to ensure that the disposable objects go out of scope.

NB: Within the using statement's code block, the declared object is read-only and cannot be reassigned.

Referencing Multiple Disposable Objects

You may require more than one disposable object of the same type. If these objects will both have the same scope you can declare them within a single using statement, each separated by a comma. For example, if our previous example had two file streams we could use:

using (Stream stream = File.OpenRead(@"c:\test\test.txt")
    , stream2 = File.OpenRead(@"c:\test\test2.txt"))
{
    // More code that uses the streams here
}

A single using statement does not permit more than one type of object to be specified. If you need to use this syntax with multiple disposable objects of differing types, you should nest using statements.

Best Practice

It is possible to declare a variable before a using statement and assign its value within the statement. However, in this case the variable will remain in scope, even though it has been disposed, beyond the closing brace of the code block. This is considered to be bad practice and should be avoided.

Stream stream;
using (stream = File.OpenRead(@"c:\test\test.txt"))
{
    // More code that uses the stream here
}
28 September 2008