在C#中实现IDisposable的正确方法是什么?

时间:2014-01-16 12:53:10

标签: c# .net idisposable

我正在尝试在c#中实现iDisposable类,但msdn和stackoverflow中的示例对我不起作用。

我在visual studio 2012 framework 4.0中运行一个控制台应用程序

我错过了一些使用或什么?

public class Foo : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
}

我正在关注这些例子(超链接对我不起作用,不知道为什么):
http://msdn.microsoft.com/en-us/library/ms244737.aspx
Implementing IDisposable correctly
How to implement IDisposable properly

5 个答案:

答案 0 :(得分:1)

您可以在Proper use of the IDisposable interface

找到合适的解释

简短的例子:

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

private void Dispose(bool disposing) {
    if (!this.disposed) {
        if (disposing) {
            // clean resources here
        }
        disposed = true;
    }
}

private bool disposed = false;

答案 1 :(得分:0)

我认为这或多或少是标准模板:

    private bool disposed = false;

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


    protected virtual void Dispose(bool disposing)
    {

        if(!disposed)
        {

            if(disposing)
            {
                // destroy managed objects here...
            }

            disposed = true;
        }
    }


    ~NameOfClass()
    {
        Dispose(false);
    }

答案 2 :(得分:0)

标准方法是使用Dispose Pattern。另请参阅this

class MyClass : IDisposable
{
    private bool alreadyDisposed = false;

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

    // This is called by GC automatically at some point if public Dispose() has not already been called
    ~MyClass()
    {
        Dispose(false);
    }

    // Each derived class should implement this method and conclude it with base.Dispose(disposeManagedResourcesAlso)) call
    protected virtual void Dispose(bool disposeManagedResourcesAlso)
    {
        if (alreadyDisposed) return;

        if (disposeManagedResourcesAlso)
        {
            ...dispose managed resources...
        }

        ...dispose unmanaged resources...

        alreadyDisposed = true; 
    }
}

答案 3 :(得分:0)

    public class MyResource: IDisposable
    {
        // Pointer to an external unmanaged resource. 
        private IntPtr handle;
        // Other managed resource this class uses. 
        private Component component = new Component();
        // Track whether Dispose has been called. 
        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;

                // Note disposing has been done.
                disposed = true;

            }
        }

        // Use interop to call the method necessary 
        // to clean up the unmanaged resource.
        [System.Runtime.InteropServices.DllImport("Kernel32")]
        private extern static Boolean CloseHandle(IntPtr handle);

        ~MyResource()
        {
            // Do not re-create Dispose clean-up code here. 
            // Calling Dispose(false) is optimal in terms of 
            // readability and maintainability.
            Dispose(false);
        }
    }

来源IDisposable Interface

答案 4 :(得分:0)

典型的IDisposable实现可能是这样的:

public class Foo: IDisposable {
  ...  

  public Boolean IsDisposed {
    get;
    protected set; // <- Or even "private set"
  }

  protected virtual void Dispose(Boolean disposing) {
    if (IsDisposed)
      return;

    if (disposing) {
      // Release all acquired resources here
    } 

    // You can work with structures (not objects!) here
    // Hardly want you to do anything here...

    IsDisposed = true;
  }

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