如何实施对物体的处理会产生其他一次性用品

时间:2018-11-20 10:11:02

标签: c# dispose idisposable

提供以下课程:

public class MyDisposableContainer : IDisposable
{
    readonly List<IDisposable> _chidlren = new List<IDisposable>();

    public void Add() => _children.Add(new FileSystemWachter());
}

我不确定应该如何实现Disposable接口。

要么:

 public void Dispose() => _children.ForEach(item => item.Dispose());

public void Dispose()
{
    // Dispose of unmanaged resources.
    Dispose(true);
    // Suppress finalization.
    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
        _children.ForEach(item => item.Dispose());
    }
}

在我的情况下,孩子是FileSystemWatcher,它使用一些不受管理的资源,因此我猜想它与终结器一起实现了一次性模式。

我猜想,第二种更长的方法是不必要的,因为无论如何,仅在显式Dispose()调用中会调用Dispose(true)。我说的对吗?

1 个答案:

答案 0 :(得分:-1)

所以简单的答案是:是的,您可以使用简单的表格

public void Dispose() => _children.ForEach(item => item.Dispose());

根据您的情况。

扩展形式

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

protected virtual void Dispose(bool disposing)
{
    if (disposing)
    {
       ...
    }
}

这是basic dispose pattern的基本实现,在这里有点多余,但是建议将其作为继承的一种很好的方式和基础,以便将来通过继承进行类的扩展(除非已密封)。

更长的答案意味着需要澄清与处置和最佳做法有关的可能情况。对象销毁过程处理两种类型的资源管理和管理。托管资源可以由GC成功处理,因此我们大多不应该为此而烦恼,而非托管资源的释放是调用代码的责任,因为GC无法跟踪它们的分配和取消分配。 IDisposable接口的目的是解决在某些对象或对象层次结构中应处理非托管资源取消分配的情况。现在,对于可能的情况:

  • 如果您的类直接保留非托管资源,则建议使用带有终结符的扩展finalizable dispose pattern,以解决外部使用者不当使用类或特殊情况的情况,以通过以下两种方式获得保证的资源分配: Dispose或终结器;
  • 如果您的课程包含其他IDisposable,但不直接拥有非托管资源,则建议的方法是使用basic dispose pattern,而不使用终结器;

注释中出现的有关销毁责任分离的注释对。每个类都应负责仅对其直接保留的那些资源进行清晰的发布处理。除了通过IDisposable或任何其他接口使用公开曝光的合同以外,它不应该尝试以其他任何方式处理基础对象的发布方案,并且不应对此做出任何假设合同。