Implementing IDisposible on light objects

J

joe.carr

Hello,
A discussion arose recently in a code review about whether or not one
should implement IDisposible (and then call it) on an object which has
neither unmanaged resources nor managed resources which are resource
intensive (db connections, filestreams, etc.). It seems to me that if
you do not have such items to explicitly dispose yourself, then it is
best to let the Garbage Collector do its work when it determines it is
the best time to clean up these objects.

But, my question is, does it matter? If I have SimpleObject, and I
call simpleObject.Dispose() when I'm done with it, is there an
associated performance liability over not calling the method?

Also, if I write an empty Dispose() method :

public void Dispose()
{

}

Is this object removed from the managed heap when I call that method?
Or is it actually cleaned up on Finalization, because it does not
suppress Finalization?

Thanks beforehand for any information.
 
J

Jon Skeet [C# MVP]

A discussion arose recently in a code review about whether or not one
should implement IDisposible (and then call it) on an object which has
neither unmanaged resources nor managed resources which are resource
intensive (db connections, filestreams, etc.). It seems to me that if
you do not have such items to explicitly dispose yourself, then it is
best to let the Garbage Collector do its work when it determines it is
the best time to clean up these objects.
Yes.

But, my question is, does it matter? If I have SimpleObject, and I
call simpleObject.Dispose() when I'm done with it, is there an
associated performance liability over not calling the method?

Well, doing "something" is always slower than doing "nothing". In
addition, there's the problem that users of your code will try to
remember the fact that you implement IDisposable, and make sure they
dispose of instances appropriately. That can, in some cases, be quite a
pain - why suggest that something is required when it's not?
Also, if I write an empty Dispose() method :

public void Dispose()
{

}

Is this object removed from the managed heap when I call that method?
No.

Or is it actually cleaned up on Finalization, because it does not
suppress Finalization?

Thanks beforehand for any information.

Unless you write a finalizer, there will be no finalization.

There is *no* magic associated with IDisposable. It's just an interface
with a single method, and it so happens that the "using" statement in
C# makes it easy to call in a try/finally block. The CLR doesn't care.
 
B

Barry Kelly

A discussion arose recently in a code review about whether or not one
should implement IDisposible (and then call it) on an object which has
neither unmanaged resources nor managed resources which are resource
intensive (db connections, filestreams, etc.).

If a class implements IDisposable, that tells me as a programmer that I
*need* to call Dispose() when appropriate. If the class doesn't own
other objects which implement IDisposable, and isn't likely to do so,
then I would say - don't implement it.

But if you do implement it, implement it properly. Create a protected
virtual void Dispose(bool disposing) method, and have your Dispose()
implementation call Dispose(true). Then put all your logic in the
protected virtual method. That way, descendants can extend the class
properly.
It seems to me that if
you do not have such items to explicitly dispose yourself, then it is
best to let the Garbage Collector do its work when it determines it is
the best time to clean up these objects.

Calling Dispose on an object whose class implements IDisposable does not
cause it to be collected ahead of time. Dispose() is just a method call,
like any other, a programming convention. There's no magic in the CLR
relating to Dispose, the only magic is in C# and its 'using' construct -
which is essentially a type-dependent macro.
But, my question is, does it matter? If I have SimpleObject, and I
call simpleObject.Dispose() when I'm done with it, is there an
associated performance liability over not calling the method?

Possibly, it will cost more, because you're pointlessly calling a
method. But the cost will be vanishingly small.
Also, if I write an empty Dispose() method :
Is this object removed from the managed heap when I call that method?

No. Explicit deallocation is asymptotically more expensive than a
copying / compacting GC like .NET's. That is, it would be more expensive
if it did remove it.
Or is it actually cleaned up on Finalization, because it does not

Only objects which implement finalizers are subject to finalization. And
objects should only implement finalizers if they need finalization, that
is, if they explicitly wrap an unmanaged resource. Typically this means
they have a field of type IntPtr, or they descend from
CriticalFinalizerObject, they call unmanaged methods via P/Invoke, etc.

-- Barry
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Top