mark_h mark_h - 3 months ago 13
C# Question

Should I always implement the dispose pattern if my class defines a field in which the field’s type implements the dispose pattern? c#

I recently read this in "CLR via C#" by Jeffery Richter;


Important If a class defines a field in which the field’s type
implements the dispose pattern, the class itself should also implement
the dispose pattern. The Dispose method should dispose of the object
referred to by the field. This allows someone using the class to call
Dispose on it, which in turn releases the resources used by the object
itself.


Would this be true in the following example?

public class SomeClass
{
private readonly StreamReader _reader; //a disposable class

public SomeClass(StreamReader reader)
{
_reader = reader;
}
}


Although StreamReader is a disposable class its intance has been passed in via the constructor, it will therefore probably be referenced somewhere else and so implementing IDisposable on SomeClass so that _reader can be disposed seems like a bad idea. Is the point that Jeffery Richter is trying to make only applicable to classes where the instances of disposable classes are instantiated within that class?

Answer

Although StreamReader is a disposable class its instance has been passed in via the constructor, it will therefore probably be referenced somewhere else and so implementing IDisposable on SomeClass

That really depends. Generally, it is a good rule of thumb to implement IDisposable when you're holding disposable resources. But, if you know for a fact that someone else is going to hold a reference to the said resource, you can create an overload in your class constructor which explicitly asks the caller if he wants you to dispose:

public class SomeClass : IDisposable
{
    private readonly StreamReader _reader; //a disposable class
    private bool shouldDispose;

    public SomeClass(StreamReader reader) : this(reader, true)
    {
    }

    public SomeClass(StreamReader reader, bool shouldDispose)
    {
        _reader = reader;
        this.shouldDispose = shouldDispose;
    }

    public void Dispose()
    {
        if (shouldDispose)
        {
            Dispose(true);
        }
    }

    protected void Dispose(bool isDisposing)
    {
        if (isDisposing)
        {
            _reader.Dispose();
        }
    }
}