15.02.2015 Views

C# 4 and .NET 4

Create successful ePaper yourself

Turn your PDF publications into a flip-book with our unique Google optimized e-Paper software.

freeing Unmanaged resources ❘ 315<br />

// do your processing<br />

}<br />

finally<br />

{<br />

if (theInstance != null)<br />

{<br />

theInstance.Dispose();<br />

}<br />

}<br />

This version ensures that Dispose() is always called on theInstance <strong>and</strong> that any resources consumed by<br />

it are always freed, even if an exception occurs during processing. However, it would make for confusing<br />

code if you always had to repeat such a construct. <strong>C#</strong> offers a syntax that you can use to guarantee that<br />

Dispose() will automatically be called against an object that implements IDisposable when its reference<br />

goes out of scope. The syntax to do this involves the using keyword — though now in a very different<br />

context, which has nothing to do with namespaces. The following code generates IL code equivalent to the<br />

try block just shown:<br />

using (ResourceGobbler theInstance = new ResourceGobbler())<br />

{<br />

// do your processing<br />

}<br />

The using statement, followed in brackets by a reference variable declaration <strong>and</strong> instantiation, will cause<br />

that variable to be scoped to the accompanying statement block. In addition, when that variable goes out<br />

of scope, its Dispose() method will be called automatically, even if an exception occurs. However, if you<br />

are already using try blocks to catch other exceptions, it is cleaner <strong>and</strong> avoids additional code indentation<br />

if you avoid the using statement <strong>and</strong> simply call Dispose() in the Finally clause of the existing try block.<br />

For some classes, the notion of a Close() method is more logical than Dispose(); for<br />

example, when dealing with fi les or database connections. In these cases, it is common<br />

to implement the IDisposable interface <strong>and</strong> then implement a separate Close()<br />

method that simply calls Dispose(). This approach provides clarity in the use of your<br />

classes but also supports the using statement provided by <strong>C#</strong>.<br />

implementing idisposable <strong>and</strong> a destructor<br />

The previous sections discussed two alternatives for freeing unmanaged resources used by the classes<br />

you create:<br />

➤<br />

➤<br />

The execution of a destructor is enforced by the runtime but is nondeterministic <strong>and</strong> places an<br />

unacceptable overhead on the runtime because of the way garbage collection works.<br />

T h e IDisposable interface provides a mechanism that allows users of a class to control when<br />

resources are freed but requires discipline to ensure that Dispose() is called.<br />

In general, the best approach is to implement both mechanisms to gain the benefi ts of both while<br />

overcoming their limitations. You implement IDisposable on the assumption that most programmers<br />

will call Dispose() correctly, but implement a destructor as a safety mechanism in case Dispose() is not<br />

called. Here is an example of a dual implementation:<br />

using System;<br />

public class ResourceHolder: IDisposable<br />

{<br />

private bool isDisposed = false;<br />

www.it-ebooks.info

Hooray! Your file is uploaded and ready to be published.

Saved successfully!

Ooh no, something went wrong!