GazTheDestroyer
GazTheDestroyer

Reputation: 21251

auto disposing of objects created in function calls

I have a series of Read() overloads in a class. Each opens the file only long enough to read, so I have:

public void Read(blah)
{
    using (FileStream stream = new FileStream(Path, FileMode.Open, FileAccess.Read))
    using (BinaryReader reader = new BinaryReader(stream))
    {
        //read some stuff        
    }
}

public void Read(blah blah)
{
    using (FileStream stream = new FileStream(Path, FileMode.Open, FileAccess.Read))
    using (BinaryReader reader = new BinaryReader(stream))
    {
        //read some different stuff        
    }
}

Is there any way of wrapping the stream and reader creation in a function, and yet still retain the using() to dispose everything automatically? eg

public void Read(blah)
{
    using (var reader = GetReader())
    {
        //read some stuff        
    }
}

public void Read(blah blah)
{
    using (var reader = GetReader())
    {
        //read some different stuff        
    }
}

private BinaryReader GetReader()
{
    //How do I dispose this stream?
    FileStream stream = new FileStream(Path, FileMode.Open, FileAccess.Read))

    return new BinaryReader(stream);
}

Upvotes: 3

Views: 1366

Answers (3)

Peter Porfy
Peter Porfy

Reputation: 9030

Because using is just a shorthand for try-finally block, you can do something like:


class Program
{
    static void Main(string[] args)
    {
        using (var b = GetReader())
        {
        }
    }

    static B GetReader()
    {
        using (var a = new A())
        {
            return new B(a);
        }
    }
}

class A : IDisposable
{

    public void Dispose()
    {
        Console.WriteLine("Dispose A");
    }
}

class B : IDisposable
{
    public B(object obj)
    {
    }

    public void Dispose()
    {
        Console.WriteLine("Dispose B");
    }
}

In your case:


public void Read(blah)
{
    using (var reader = GetReader())
    {
        //read some stuff        
    }
}

public void Read(blah blah)
{
    using (var reader = GetReader())
    {
        //read some different stuff        
    }
}

private BinaryReader GetReader()
{
    //How do I dispose this stream?
    using(FileStream stream = new FileStream(Path, FileMode.Open, FileAccess.Read))
    {
        return new BinaryReader(stream);
    }
}

Upvotes: 0

Rich O'Kelly
Rich O'Kelly

Reputation: 41757

In this particular case, BinaryReader is responsible for the passed stream and will Close it properly on disposal.

If however you wish to avoid such boilerplate in the future, the following may serve as a useful example:

private class MyReader : BinaryReader, IDisposable
    {
        private readonly Stream _input;

        public MyReader(Stream input) : base(input)
        {
            _input = input;
        }

        void IDisposable.Dispose()
        {
            Dispose();
            _input.Dispose();
        }
    }

Upvotes: 1

Kevin Gosse
Kevin Gosse

Reputation: 39007

In this specific case, you don't have to dispose your stream. Upon disposal, the BinaryReader will automatically dispose the underlying stream.

But maybe the BinaryReader is just an example?

Upvotes: 3

Related Questions