Nope, not anything goes. Like all programming, there are rules and
gotchas.
I'm pretty sure that all objects which implement the IDisposable
interface use unmanaged resources; i.e. they end up being a wrapper to
a COM DLL call, which .Net cannot know what other programs are using
that particular COM object server. So .Net can't free unmanaged
resources automatically, because other applications may actually be
using those same resources.
The rule is, if the object has a Dispose or Close method, make SURE you
call it when you are done with it. If you're using anything from
System.IO, System.Windows.Forms, and System.Data.* you'll defaintly
come across such classes. There are others throughout the framework as
well.
As long as you follow that rule, you'll be fine. As an example, if
your class opens a database connection when an object is instanciated
from that class and keeps the connection around the entire lifetime of
your object, you should implement IDisposable as well. Your dispose
method would make sure to Dispose the database connection. Its up to
the client of your object to call Dispose on your object.
I think that if you don't call Dispose, eventually it will be called
when the garbage collector finalizes the objects, but that is a HUGE
performance hit, and in the case of a database connection, you keep a
connection open much longer than you really need to. So you shouldn't
rely on the finalizer.
I had a bug in my custom Data access layer used by my application where
my SqlDataReaders weren't being disposed after I was done using them.
What ended up happening was that each instance of my application
started using about 10 - 20 different connections to the Sql server, to
the point where the server wasn't responding as well and data
operations started getting exceptions when it tried to open a new
connection. This happened pretty quickly because even though I had a
few users, every 30 seconds the app would hit the database. The bug
was in my data layers Find code; I wasn't disposing the DataReader when
I was done. I just put the data reader into a using( ) {} block,
recompiled and distributed the new application.. now the app uses one
connection (via connection pooling) to do its work, there are no more
errors and the server is very responsive again. The moral is to always
make sure to dispose your disposable objects, using the using block (in
C#, VB has an equivelent).
HTH
Andy