【问题标题】:does dispose method disposes the calling object also?dispose 方法是否也会处理调用对象?
【发布时间】:2013-01-23 22:44:40
【问题描述】:

我在 MSDN 上找到了以下代码:

public class DisposeExample
{

    public class MyResource: IDisposable
    {    
        private IntPtr handle;
        private Component component = new Component(); 
        private bool disposed = false;

        public MyResource(IntPtr handle)
        {
            this.handle = handle;
        }

        public void Dispose()
        {
            Dispose(true);

            GC.SuppressFinalize(this);
        }


        protected virtual void Dispose(bool disposing)
        {
            if(!this.disposed)
            {

                if(disposing)
                {
                    // Dispose managed resources.
                    component.Dispose();
                }


                CloseHandle(handle);
                handle = IntPtr.Zero;

                disposed = true;

            }
        }

        ~MyResource()
        {
            Dispose(false);
        }
    }
    public static void Main()
    {
        MyResource obj = new MyResource()
        //obj.dispose()
    }
}

现在我的困惑是,如果我调用 obj.dispose,它会处理在 MyResources 类中创建的对象,即句柄、组件等。但是 obj 是否也会从堆中删除?同样适用于析构函数。如果我不调用 dispose,则有时会调用析构函数。析构函数中的代码删除了包含的对象。但是obj呢? 其次,如果我没有在类中定义析构函数并且我什至不调用 dispose,GC 是否永远不会出现在这里?

【问题讨论】:

    标签: garbage-collection dispose idisposable finalize


    【解决方案1】:

    IDisposable 的存在是为了从您的托管对象中删除非托管项目。运行时自动提供了一个析构函数,这个析构函数在这里的唯一目的是释放非托管项。一旦您的对象超出范围或设置为 null 并且没有更多对其的引用,GC 最终将清除该对象。

    【讨论】:

    • 让我解释一下: - 如果我没有在析构函数中调用,则只会处理 obj 的托管对象,而将非托管对象保持原样。 - 如果我根本没有定义析构函数,一旦 obj 的作用域消失,就会调用析构函数来完全删除对象以及包含的托管/非托管对象。如果这样的话,包含非托管对象也会死掉,为什么还要费心去调用 dispose 方法呢?
    • 在这里考虑这篇文章,它应该可以帮助你:IDisposable。考虑“IDisposable 解决方案”段落。
    【解决方案2】:

    我建议使用 IDisposable 的基本规则是,在任何给定时间,对于实现 IDisposable 的每个对象,都应该有一个明确定义的实体负责确保将其清理干净(几乎总是通过调用Dispose)在它被放弃之前。这种责任最初属于调用IDidposable 对象构造函数的任何实体,但该实体可能会将责任移交给其他实体(可能会再次移交,等等)。

    一般来说,我猜大多数程序员最好假装终结器和析构函数不存在。它们通常只在代码编写不佳的情况下才需要,并且在大多数情况下,人们必须花费精力编写 100% 正确的终结器/析构器并解决与线程上下文、意外复活等相关的所有棘手问题. 可以更好地确保始终遵循上面给出的主要规则。由于框架及其语言中的一些不幸的设计决策,有一些情况在没有终结器/析构函数的情况下无法很好地处理,但在大多数情况下,它们用于将相对较快失败的代码转换为将大部分都可以工作,但有时可能会以几乎无法调试的方式失败。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2010-12-30
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2011-06-30
      相关资源
      最近更新 更多