C#中最简单的IDisposable模式是什么?

3

如果我的类仅使用托管资源,所以我认为没有必要完全实现IDisposable模式。

这应该是足够的:

    public class ManagedResourceClient : IDisposable
    {
        private ITheManagedResource _myManagedResource = new TheManagedResource()

        public void Dispose()
        {
            if ( _myManagedResource != null )
            {
                _myManagedResource.Dispose();
                _myManagedResource = null;
            }
        } 
    }

我看不到使用下列方法的理由:
  • 使用终结器,因为它只使用了实现了IDisposable接口的托管资源
  • 使用“disposing”标志,因为可以通过检查是否为空来处理
  • 使用虚拟的Disposing方法,因为没有必要区分GC调用和直接调用。
以上内容是否正确?

1
这个应用程序是多线程的吗? - Marshall Tigerus
3
我有一个只使用托管资源的类。那么你可能不需要进行dispose(释放非托管资源)操作。 - Steve
1
@Servy:voila,下一个没有任何原因实现IDisposable接口的对象。 - Tim Schmelter
1
你说你有一个继承自ManagedResourceClient的类,它使用了许多非托管资源。你又重新实现了IDisposable接口!!这里需要使用你的虚拟Dispose(bool)方法。 - Med.Amine.Touil
1
OP,您需要说明您是否正在使用非托管资源。如果整个应用程序仅使用托管资源,则不需要。 - Steve
显示剩余19条评论
1个回答

5

你几乎做到了,因为你的类没有被密封,所以有人可以从你的类派生出一个子类,并且这个派生类也可能需要处理对象的释放。将你的类密封起来,你当前的实现就很好了。

public sealed class ManagedResourceClient : IDisposable
{
    private ITheManagedResource _myManagedResource = new TheManagedResource()

    public void Dispose()
    {
        if ( _myManagedResource != null )
        {
            _myManagedResource.Dispose();
            _myManagedResource = null;
        }
    } 
}

如果你想学习更多关于资源释放(以及为什么微软提供的一个带有终结器的存储示例实际上是一个糟糕的例子),请看 Stepen Cleary 写的这篇非常好的文章:“IDisposable: What Your Mother Never Told You About Resource Deallocation”。


好的,谢谢。如果它没有被密封,我需要做什么? - user183872
@user183872 将Dispose函数设为虚函数或者将其设为受保护的虚函数(将其设为受保护的函数是“标准”的Dispose模式)。 - Scott Chamberlain
你应该确保阅读这篇文章,基本上它解释了为什么除非你的类派生自SafeHandle,否则你永远不需要在你的类中使用终结器。你将你的逻辑分成两种类型,一种只处理单个非托管对象(Type 0),另一种只包含 Type 0 或其他 Type 1 对象(Type 1)。 - Scott Chamberlain
@Scott - 在现实中,Dispose模式会出现问题吗?(除了程序员未能调用.dispose之外)- 这篇文章中的内容是真实世界中的问题还是理论上的问题? - Cato
@Cato 主要的现实情况是,如果您正在生成大量短暂的一次性对象,则在您的可处理对象上设置终结器会导致您的对象永远不会作为 Gen 0 垃圾回收的一部分被收集,因为拥有终结器会使您在添加到终结器队列时晋升一个层级。当您有大量非常短暂的可处理对象时,这可能会导致明显的性能问题。 - Scott Chamberlain
@ScottChamberlain 那篇文章非常棒!感谢您的参考。 - user183872

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接