The using statement obtains one or more resources, executes a statement, and
then disposes of the resource.
using-statement:
using ( resource-acquisition ) embedded-statement
resource-acquisition:
local-variable-declaration
expression
A resource is a class or struct that implements System.IDisposable, which
includes a single
parameterless method named Dispose. Code that is using a resource can call
Dispose to indicate that the
resource is no longer needed. If Dispose is not called, then automatic
disposal eventually occurs as a
consequence of garbage collection.
If the form of resource-acquisition is local-variable-declaration then the
type of the local-variabledeclaration
must be System.IDisposable or a type that can be implicitly converted to
System.IDisposable. If the form of resource-acquisition is expression then
this expression must be
System.IDisposable or a type that can be implicitly converted to
System.IDisposable.
Chapter 15 Statements
199
Local variables declared in a resource-acquisition are read-only, and must
include an initializer. A compiletime
error occurs if the embedded statement attempts to modify these local
variables (via assignment or the
++ and -- operators) or pass them as ref or out parameters.
A using statement is translated into three parts: acquisition, usage, and
disposal. Usage of the resource is
implicitly enclosed in a try statement that includes a finally clause. This
finally clause disposes of the
resource. If a null resource is acquired, then no call to Dispose is made,
and no exception is thrown.
A using statement of the form
using (ResourceType resource = expression) statement
corresponds to one of two possible expansions. When ResourceType is a value
type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
((IDisposable)resource).Dispose();
}
}
Otherwise, when ResourceType is a reference type, the expansion is
{
ResourceType resource = expression;
try {
statement;
}
finally {
if (resource != null) ((IDisposable)resource).Dispose();
}
}
In either expansion, the resource variable is read-only in the embedded
statement.
A using statement of the form
using (expression) statement
has the same two possible expansions, but in this case ResourceType is
implicitly the compile-time type of
the expression, and the resource variable is inaccessible in, and invisible
to, the embedded statement.
When a resource-acquisition takes the form of a local-variable-declaration,
it is possible to acquire multiple
resources of a given type. A using statement of the form
using (ResourceType r1 = e1, r2 = e2, ..., rN = eN) statement
is precisely equivalent to a sequence of nested using statements:
using (ResourceType r1 = e1)
using (ResourceType r2 = e2)
...
using (ResourceType rN = eN)
statement
[Example: The example below creates a file named log.txt and writes two
lines of text to the file. The
example then opens that same file for reading and copies the contained
lines of text to the console.
using System;
using System.IO;
class Test
{
static void Main() {
using (TextWriter w = File.CreateText("log.txt")) {
w.WriteLine("This is line one");
w.WriteLine("This is line two");
}
C# LANGUAGE SPECIFICATION
200
using (TextReader r = File.OpenText("log.txt")) {
string s;
while ((s = r.ReadLine()) != null) {
Console.WriteLine(s);
}
}
}
}
Since the TextWriter and TextReader classes implement the IDisposable
interface, the example can
use using statements to ensure that the underlying file is properly closed
following the write or read
operations. end example]