The MSDN documentation and many answers here on StackOverflow go to lengths to disucss correctly implementing IDisposable
, e.g. MSDN IDisposable, MSDN Implementing IDisposable, An excellent StackOverflow Q&A
However none of them seem to cover a more common use-case I have: what to do when my class has an IDisposable
member that lives longer than one method? For example
class FantasticFileService { private FileSystemWatcher fileWatch; // FileSystemWatcher is IDisposable public FantasticFileService(string path) { fileWatch = new FileSystemWatcher(path); fileWatch.Changed += OnFileChanged; } private void OnFileChanged(object sender, FileSystemEventArgs e) { // blah blah } }
The closest MSDN gets to addressing this problem only covers the use-case when the instance of IDisposable
is short lived so says call Dispose
e.g. by using using
:
Implement IDisposable only if you are using unmanaged resources directly. If your app simply uses an object that implements IDisposable, don't provide an IDisposable implementation. Instead, you should call the object's IDisposable.Dispose implementation when you are finished using it.
of course that is not possible here where we need the instance to survive longer than a method call!?
I suspect the correct way to do this would be to implement IDisposable
(passing the responsibility to creator of my class to dispose it) but without all finalizer and protected virtual void Dispose(bool disposing)
logic becuase I don't have any unmanged resources, i.e.:
class FantasticFileService : IDisposable { private FileSystemWatcher fileWatch; // FileSystemWatcher is IDisposable public FantasticFileService(string watch) { fileWatch = new FileSystemWatcher(watch); fileWatch.Changed += OnFileChanged; } public void Dispose() { fileWatch.Dispose(); } }
But why is this use-case not explicitly covered in any official documentation? And the fact it explicitly says do not implement IDisposable
if your class does not have unmanaged resources makes me hesitant to do so... What is a poor programmer to do?
If you access unmanaged resources (e.g. files, database connections etc.) in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed.
If your class creates unmanaged resources, then you can implement IDisposable so that these resources will be cleaned up properly when the object is disposed of. You override Dispose and release them there.
IDisposable is usually used when a class has some expensive or unmanaged resources allocated which need to be released after their usage. Not disposing an object can lead to memory leaks.
If a type implements the IDisposable interface, you should always call the Dispose method on an instance of the class when you are done using it. The presence of IDisposable indicates that the class has some resources that can be released prior to garbage collection.
It looks like your case is indeed covered by some documentation, namely the design warning CA1001: Types that own disposable fields should be disposable.
That link has an example of what your IDisposable
implementation should look like. It will be something like as follows. Eventual design guidelines can be found at CA1063: Implement IDisposable correctly.
class FantasticFileService : IDisposable { private FileSystemWatcher fileWatch; // FileSystemWatcher is IDisposable public FantasticFileService(string watch) { fileWatch = new FileSystemWatcher(watch); fileWatch.Changed += OnFileChanged; } ~FantasticFileService() { Dispose(false); } protected virtual void Dispose(bool disposing) { if (disposing && fileWatch != null) { fileWatch.Dispose(); fileWatch = null; } } public void Dispose() { Dispose(true); GC.SuppressFinalize(this); } }
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With