使用一次性模式清理IDispose成员类

时间:2015-08-10 00:21:24

标签: c# dispose idisposable

部分一次性模式包括以下方法。

protected virtual void Dispose(bool disposing)
{
    if (!disposed)
    {
        if (disposing)
        {
            // TODO: dispose managed state (managed objects).
        }

        // TODO: free unmanaged resources (unmanaged objects) and override a finalizer below.
        // TODO: set large fields to null.
        disposed = true;
    }
}

此方法具有不同的处理方式来清理托管和非托管资源。但是如果我想清理一个实现IDisposable的类成员呢?

通常情况下,我不知道该成员是否清理了托管或非托管资源。因此,如果我希望我的Dispose方法清理实现IDisposable的类成员,我是否会在上面代码中托管或非托管部分的该成员上调用Dispose()

2 个答案:

答案 0 :(得分:3)

您应该在托管部分调用Dispose(即,仅当disposing为真时)。

框架设计指南中Dispose Pattern的部分指导原则是:

  

布尔参数disposing指示是从IDisposable.Dispose实现还是从终结器调用方法。 Dispose(bool)实现应该在访问其他引用对象之前检查参数[...]。只有在从IDisposable.Dispose实现调用方法时才会访问此类对象(当disposing参数等于true时)。如果从终结器调用该方法(disposing为false),则不应访问其他对象。原因是对象以不可预测的顺序最终确定,因此它们或它们的任何依赖项可能已经完成。

另一个有用的资源是Implementing a Dispose Method

答案 1 :(得分:1)

处理实现IDisposable的类成员的标准方法是这样的:

public class Foo : IDisposable
{
    // MemoryStream implements IDisposable
    private readonly Stream _stream = new MemoryStream();

    private bool _disposed;

    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        if (_disposed)
        {
            return;
        }

        if (disposing)
        {
            _stream.Dispose();
        }

        _disposed = true;
    }
}

澄清一下,清理托管的资源意味着资源本身实现了IDisposable(如上面MemoryStream所做的那样)。 MemoryStream / Stream拥有基础非托管资源,并且已经为您实现了清理逻辑。无需清除Foo中的非托管资源。