自动处理在函数调用中创建的对象

本文关键字:创建 对象 函数调用 处理 | 更新日期: 2023-09-27 18:16:27

我在一个类中有一系列Read()重载。每个打开文件的时间只够读,所以我有:

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        
    }
}
是否有任何方法可以将流和阅读器创建包装在函数中,但仍然保留using()来自动处理所有内容?如
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);
}

自动处理在函数调用中创建的对象

在这种特殊情况下,您不必处置流。一旦被释放,BinaryReader将自动释放底层流。

但也许BinaryReader只是一个例子?

在这种特殊情况下,BinaryReader负责传递的流,并将在处理时正确关闭它。

如果你希望在将来避免这样的样板文件,下面的代码可以作为一个有用的例子:

private class MyReader : BinaryReader, IDisposable
    {
        private readonly Stream _input;
        public MyReader(Stream input) : base(input)
        {
            _input = input;
        }
        void IDisposable.Dispose()
        {
            Dispose();
            _input.Dispose();
        }
    }

因为using只是try-finally块的简写,所以您可以这样做:


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");
    }
}

在你的例子中:


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);
    }
}