I have a class (myClass), which has a class member (myDisposableMem) derived from IDisposable, thus having a Dispose() method. If it was a local variable, I can use using(…) {…} to make sure Dispose() will be called on this object. But it is a class member. What is the right way to make sure the Disposed is called on the member? I can think of 2 ways:
1) add a finallize() in the class, then call myDisposableMem.Dispose() inside
or
2) make my class inherit from IDisposible:
public class myClass : IDisposable
{
...
public void Dispose()
{
myDisposableMem.Dispose();
}
}
void main ()
{
using (myClass myObj = new MyClass())
{
....
}
}
Or maybe there is a better way?
Finalization and implementing
IDisposableare not two separate options; they should always be done together. You should always implementIDisposableand clean up your resources inDispose(), so that users can ensure that unmanaged resources are cleaned up in a timely fashion. And youDispose()method should always finish off by calling GC.SuppressFinalize(this) to make sure its finalizer doesn’t get called, for reasons that will be explained in a moment.You should always implementNope. See Ilian Pinzon’s comments below, and I’ve apparently got some documentation to try reading again.~MyObject()when you implementIDisposable. Its purpose is to give the garbage collector a way to ensure your object is always disposed of in case the people who are using it fail to take care of that themselves. If your finalizer is doing much more than callingthis.Dispose()then you’re probably using it incorrectly.It’s really just a safety net. Ideally, the finalizer should actually never be called, because objects are always explicitly disposed instead. When the garbage collector invokes it, it’s forced to skip collecting that object. That in turn means that it gets passed along to the second garbage collector generation. Which in turn means that the object will stay in memory much longer, and ultimately be more expensive to clean up.
See here and here for more information on how it should be done.
That said, the best option is to get those disposable objects out of the class context and make them method variables instead whenever possible.
For example, if you’ve got a class that connects to a database, don’t store a master instance of
SqlConnectionas a field. Instead, have your public methods create their own connections, and pass them to private methods as needed. This has two advantages: First, it means that you can declare yourSqlConnectionsinusingblocks and be done with it. Second, getting rid of that piece of ‘global’ state will help with thread safety, if you ever need it. (There are other advantages specific to `SqlConnection, but those are the general ones.)