在C#中如何覆盖Finalize()方法?

时间:2010-05-26 13:02:03

标签: c#

以下函数给出编译错误“不要覆盖object.Finalize。而是提供析构函数。”

protected override void Finalize()
{           
    this.Dispose();
    base.Finalize();
}

3 个答案:

答案 0 :(得分:18)

终结器方法称为~name(),用您的类名替换“name”。

C#编译器将从此生成终结器。

但请注意:

  1. 如果您确实需要,只使用终结器:您的直接类型包含本机资源(组成包装器的类型只使用Dispose模式)。
  2. 考虑专注SafeHandle,而不是自己编写。
  3. 实施dispose模式以允许调用者快速释放资源。
  4. 确保Dispose和Finalizer都是幂等的 - 可以多次安全地调用它们。
  5. e.g。

    class MyClass : IDisposable {
      private IntPtr SomeNativeResource;
    
      ~MyClass() {
        Dispose(false);
      }
    
      public void Dispose() {
        Dispose(true);
      }
    
      protected virtual void Dispose(bool disposing) {
        if (disposing) {
          // Dispose any disposable fields here
          GC.SuppressFinalize(this);
        }
        ReleaseNativeResource();
      }
    }
    

    子类可以覆盖Dispose(bool)以添加它们添加的任何添加字段并调用基本实现。

    已编辑:添加有关何时完成的示例和说明。

答案 1 :(得分:8)

你没有。

收听编译器。你不应该覆盖Finalize。相反,您应该实现IDisposible并覆盖Dispose。

除非您明确需要释放对象直接拥有的资源,否则您应该能够在Dispose方法中执行所需的所有操作。

但如果你必须:

public class MyClass
{
    public MyClass() { ... } // Constructor
    public ~MyClass() { ... } // Destructor/Finalizer
}

要小心,因为终结器很棘手,如果实施不当会导致一些非常大的性能开销。

答案 2 :(得分:0)

听取编译器错误,他们的智慧超出了他们的年限(除非你真的需要,在极少数情况下,实际上弄乱了终结器......命名在C#中有点倒退)。

您应该实现Dispose(),使您的类实现IDisposable,如下所示:

public class MyClass : IDisposable
{
  public void Dispose()
  {
    //cleanup
  }
}

然后在使用你的课时,将它包装在using中,如下所示:

using(var mc = new MyClass()) {
 //use it for things
} //it gets disposed here