???
Even though the IDisposable pattern provides a form of deterministic destruction, it is
not a perfect solution. Using IDisposable, the onus is thrown on the client to ensure that the
Dispose method is called. There is no way for the client to rely upon the system, or the compiler,
to call it automatically.
When you implement Dispose(), you normally implement the class in such a way that
the finalizer code reuses Dispose(). This way, if the client code never calls Dispose(), the
finalizer code will take care of it at finalization time. Another factor that makes implementing
IDisposable challenging for objects is that you must chain calls of IDisposable if your object
contains references to other objects that support IDisposable. This makes designing classes a
little more difficult, since you must know whether a class that you use for a field type implements
IDisposable; and if it does, you must implement IDisposable, and you must make sure
to call its Dispose method inside yours.
Given all of this discussion regarding IDisposable, you can definitely start to see how the
garbage collector adds complexity to design, even though it reduces the chance for memory
bugs. Let??™s look at an example implementation of IDisposable:
CHAPTER 3 n CLASSES AND STRUCTURES 63
Imports System
Public Class A
Implements IDisposable
Private Disposed As Boolean = False
Public Sub Dispose(ByVal Disposing As Boolean)
If Not Disposed Then
If Disposing Then
'It is safe to access other objects here.
Pages:
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134