Vince P <vincep1974 COMCAST.NET> wrote:
> (To no one in particular)
Heh.
> I've run into a world of hurt not calling Dispose on
my SqlConnections when
> doing data extraction via DataAdapters and an error
occurs. That was the
> beginning of my awareness that my previously cavalier
attitude toward
> IDisposible was impacting my users.
>
> I remember asking about IDisposible and Finalizers a
few months ago and the
> consensus seemed to be (IIRC) that if the only
"cleanup" was unmanaged
> resources than all that should be done in Dispose and
that I shouldn't even
> make a Finalizer method because of performance issues
and some other issues
> that resulted in Finalizers just getting in the way or
being redundant.
You should only write a finalizer if the object is itself
directly
wrapping an unmanaged resource. So, if you write a new kind
of
FileStream object, or some object that wraps an unmanaged
resource by
descending from SafeHandle (recommended, it implements the
finalizer for
you) or has a private field of type IntPtr that's used to
hold something
gotten using P/Invoke, then you've likely got reason to
implement a
finalizer. It's not every day that one needs to wrap an
unmanaged
resource, so one should almost never need to implement a
finalizer.
If your object is simply using other managed objects
(whether or not
they implement IDisposable or have a finalizer themselves),
then you
don't need to (and shouldn't) implement a finalizer.
If your object logically owns other managed objects which
implement
IDisposable, then it should implement the IDisposable
pattern itself,
along the lines below:
---8<---
class MyClass : IDisposable // only if a base class doesn't
implement it
{
private IDisposable _myOwnedObject; // This object is
strictly owned
// by this MyClass instance, and never needs to outlive
its parent.
// ...
public Dispose()
{
Dispose(true);
GC.SuppressFinalize(this); // Only needed because a
descendant
// might some day override the finalizer.
}
// This method should be virtual unless the class is
sealed.
// If there is an ancestor which implements
Dispose(bool), then it
// should be overridden instead of defining a new one.
protected virtual void Dispose(bool disposing)
{
if (disposing)
{
_myOwnedObject.Dispose();
// other owned objects disposed
}
}
}
---8>---
This is probably just reiterating what you've already read
as the
consensus, but I keep repeating it because many people
don't distinguish
between the cases for implementing IDisposable versus the
cases for
implementing a finalizer. IDisposable is common; finalizers
are rare.
-- Barry
--
http://barrkel.blogspot.
com/
===================================
This list is hosted by DevelopMentorŪ http://www.develop.com
View archives and manage your subscription(s) at http://discuss.develop.com
|