I have a class that uses a filestream. It needs to close the stream when the app shuts down, so I make the class implement IDisposable.
That class is a member of another class, which is a member of another class etc. All the way up to my main app.
Do I therefore have to implement IDisposable on all of these classes?
What if I change my file implementation in the future so that it closes the file after each write? I now have a whole set of classes that implement IDisposable for no reason.
I guess I'm uncomfortable with crowbarring IDisposable semantics into classes that have no need for them other than some slight implementation detail way down the chain. Are there any ways around this?
Typically, types that use unmanaged resources implement the IDisposable or IAsyncDisposable interface to allow the unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you call the object's Dispose or DisposeAsync implementation to explicitly perform cleanup.
For implementing the IDisposable design pattern, the class which deals with unmanaged objects directly or indirectly should implement the IDisposable interface. And implement the method Dispose declared inside of the IDisposable interface. We do not directly deal with unmanaged objects.
IDisposable is an interface that contains a single method, Dispose(), for releasing unmanaged resources, like files, streams, database connections and so on.
The class should always contain the protected virtual void Dispose(bool) method because this method allows the derived classes to correctly dispose the resources of this class. The code or content of the Dispose() method should be only the invocation of Dispose(true) followed by GC. SuppressFinalize(this).
In general if your type contains a member that implements IDisposable
the type should also implement IDiposable
as well. It's the easiest way to enforce the IDisposable
pattern.
The one exception I use is if my types contract contains a method which 1) must be called and 2) signals the end of use for the IDisposable
resource. In that case I feel comfortable not implementing IDisposable
and instead using that method to call Dispose
If you explicitly want to dispose the filestream, then yes, you need Implement IDisposable on any classes that hold a reference to your IDisposable. If it is reasonable to dispose the filestream after each write, i.e. does not hurt performance due to frequent wries, that sounds preferrable.
It depends on how you implement the class that uses the filestream. If that class creates the filestream, then it should be responsible for disposing of it. However, if you were to change it so the method took in a filestream as a parameter, it would no longer 'own' the filestream and therefore not be responsible for disposing of it.
If the class is part of some kind of hierarchy, you can just add a filestream as a parameter starting at the top and introduce it to all methods down to where it is actually used.
For example:
public class Class1
{
private readonly Class2 SomeObject = new Class2();
public void DoWork1(Filestream stream)
{
SomeObject.DoWork2(stream);
}
}
public class Class2
{
public void DoWork2(Filestream stream)
{
// Do the work required with the Filestream object
}
}
While I'm not sure I'd use this pattern myself, this will allow you to not have to add 'IDisposable' to any classes except for the one that originally created the Filestream object.
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