Permalink
Fetching contributors…
Cannot retrieve contributors at this time
63 lines (41 sloc) 4.97 KB
title ms.date ms.technology dev_langs helpviewer_keywords ms.assetid author ms.author
Using objects that implement IDisposable
04/07/2017
dotnet-standard
csharp
vb
Dispose method
try/finally block
garbage collection, encapsulating resources
81b2cdb5-c91a-4a31-9c83-eadc52da5cf0
rpetrusha
ronpet

Using objects that implement IDisposable

The common language runtime's garbage collector reclaims the memory used by managed objects, but types that use unmanaged resources implement the xref:System.IDisposable interface to allow the memory allocated to these unmanaged resources to be reclaimed. When you finish using an object that implements xref:System.IDisposable, you should call the object's xref:System.IDisposable.Dispose%2A?displayProperty=nameWithType implementation. You can do this in one of two ways:

  • With the C# using statement or the Visual Basic Using statement.

  • By implementing a try/finally block.

The using statement

The using statement in C# and the Using statement in Visual Basic simplify the code that you must write to create and clean up an object. The using statement obtains one or more resources, executes the statements that you specify, and automatically disposes of the object. However, the using statement is useful only for objects that are used within the scope of the method in which they are constructed.

The following example uses the using statement to create and release a xref:System.IO.StreamReader?displayProperty=nameWithType object.

[!code-csharpConceptual.Disposable#1] [!code-vbConceptual.Disposable#1]

Note that although the xref:System.IO.StreamReader class implements the xref:System.IDisposable interface, which indicates that it uses an unmanaged resource, the example doesn't explicitly call the xref:System.IO.StreamReader.Dispose%2A?displayProperty=nameWithType method. When the C# or Visual Basic compiler encounters the using statement, it emits intermediate language (IL) that is equivalent to the following code that explicitly contains a try/finally block.

[!code-csharpConceptual.Disposable#3] [!code-vbConceptual.Disposable#3]

The C# using statement also allows you to acquire multiple resources in a single statement, which is internally equivalent to nested using statements. The following example instantiates two xref:System.IO.StreamReader objects to read the contents of two different files.

[!code-csharpConceptual.Disposable#4]

Try/finally block

Instead of wrapping a try/finally block in a using statement, you may choose to implement the try/finally block directly. This may be your personal coding style, or you might want to do this for one of the following reasons:

  • To include a catch block to handle any exceptions thrown in the try block. Otherwise, any exceptions thrown by the using statement are unhandled, as are any exceptions thrown within the using block if a try/catch block isn't present.

  • To instantiate an object that implements xref:System.IDisposable whose scope is not local to the block within which it is declared.

The following example is similar to the previous example, except that it uses a try/catch/finally block to instantiate, use, and dispose of a xref:System.IO.StreamReader object, and to handle any exceptions thrown by the xref:System.IO.StreamReader constructor and its xref:System.IO.StreamReader.ReadToEnd%2A method. Note that the code in the finally block checks that the object that implements xref:System.IDisposable isn't null before it calls the xref:System.IDisposable.Dispose%2A method. Failure to do this can result in a xref:System.NullReferenceException exception at run time.

[!code-csharpConceptual.Disposable#6] [!code-vbConceptual.Disposable#6]

You can follow this basic pattern if you choose to implement or must implement a try/finally block, because your programming language doesn't support a using statement but does allow direct calls to the xref:System.IDisposable.Dispose%2A method.

See also