简体   繁体   中英

In C# how to override the Finalize() method?

Following function giving compilation error "Do not override object.Finalize. Instead, provide a destructor."

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

The finalizer method is called ~name() replacing "name" with your class name.

The C# compiler will generate the finalizer from this.

But note:

  1. Only use a finaliser if you really need it: your type directly contains a native resource (a type composing a wrapper just uses the Dispose pattern).
  2. Consider specialising SafeHandle rather than writing your own.
  3. Implement the dispose pattern to allow callers to release the resource quickly.
  4. Ensure both your Dispose and Finalizer are idempotent—they can be safely called multiple times.

eg

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();
  }
}

Subclasses can override Dispose(bool) to add any addition fields they add and call the base implementation.

EDITED: To add example and notes about when to finalise.

You don't.

Listen to the compiler. You shouldn't override Finalize. Instead, you should implement IDisposible and override Dispose.

Unless you explicitly need to free resources held directly by the object, you should be able to do everything you need to in the Dispose method.

But if you must:

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

Just be careful because Finalizers are tricky and if implemented improperly can carry some pretty hefty performance overhead.

Listen to compiler errors, they are wise beyond their years (unless you really need to, in the rare case, actually mess with the finalizer...the naming's a bit backwards in C#).

You should instead implement Dispose() , making your class implement IDisposable , like this:

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

Then when using your class, wrap it in a using , like this:

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM