C#中的Finalize和Dispose有什么区别?

完成

在回收有资格进行收集的对象之前,垃圾收集器将调用Finalize()。垃圾收集器将负责为未引用的对象分配内存。内存中不再有对该对象的有效引用后,垃圾收集器会在某个时候调用此方法。

该框架不能保证当这种情况发生时,我们可以强制进行垃圾回收,但这会损害程序的性能。Finalize()属于Object类,运行时将调用它。

示例

using System;
namespace DemoApplication{
   public class Demo{
      ~Demo(){
         Console.WriteLine("Finalize called");
      }
   }
}

处理

有一些资源,例如Windows句柄,数据库连接,网络连接,文件等,这些资源无法由垃圾收集器收集。如果我们要显式释放某些特定对象,那么这是实现IDisposable并覆盖Dispose()IDisposable接口方法的最佳选择。

Dispose()方法不会自动调用,当不再需要对象时,我们必须从客户端应用程序中显式调用它。Dispose()即使对该对象的其他引用仍然有效,也可以调用。

示例

using System;
namespace DemoApplication{
   public class Demo : IDisposable{
      private bool disposed = false;
      public void Dispose(){
         Dispose(true);
         GC.SuppressFinalize(this);
      }
      protected virtual void Dispose(bool disposing){
         if (!disposed){
            if (disposing){
               //清理托管对象
            }
            //清理非托管对象
            disposed = true;
         }
      }
   }
}

Microsoft建议在使用非托管资源时,我们同时实现Dispose和Finalize。当对象被垃圾回收时,即使开发人员忽略了显式调用Dispose方法,Finalize实现也将运行,并且资源仍将被释放。