En C #, ¿cuál es la diferencia entre un destructor y un método Finalize en una clase?

¿Cuál es la diferencia, si hay una, entre un destructor y un método Finalize en una clase?

Recientemente descubrí que Visual Studio 2008 considera un destructor sinónimo de un método Finalize, lo que significa que Visual Studio no le permitirá definir simultáneamente ambos métodos en una clase.

Por ejemplo, el siguiente fragmento de código:

class TestFinalize { ~TestFinalize() { Finalize(); } public bool Finalize() { return true; } } 

Da el siguiente error en la llamada a Finalizar en el destructor:

La llamada es ambigua entre los siguientes métodos o propiedades: ‘TestFinalize. ~ TestFinalize ()’ y ‘TestFinalize.Finalize ()’

Y si la llamada a Finalize está comentada, da el siguiente error:

Escriba ‘ManagementConcepts.Service.TestFinalize’ ya define un miembro llamado ‘Finalize’ con los mismos tipos de parámetros

Un destructor en C # anula el método System.Object.Finalize . Tienes que usar la syntax del destructor para hacerlo. Anular manualmente Finalize le dará un mensaje de error.

Básicamente, lo que intenta hacer con su statement de método Finalize es ocultar el método de la clase base. Hará que el comstackdor emita una advertencia que se puede silenciar con el new modificador (si fuera a funcionar). Lo importante a tener en cuenta aquí es que no puede override y declarar un new miembro con nombre idéntico al mismo tiempo, por lo que tener un destructor y un método Finalize dará como resultado un error (pero puede , aunque no se recomienda, declarar un public new void Finalize() método public new void Finalize() si no está declarando un destructor).

Wikipedia tiene una buena discusión sobre la diferencia entre un finalizador y un destructor en el artículo del finalizador .

C # realmente no tiene un destructor “verdadero”. La syntax se asemeja a un destructor de C ++, pero realmente es un finalizador. Lo escribió correctamente en la primera parte de su ejemplo:

 ~ClassName() { } 

Lo anterior es azúcar sintáctico para una función Finalize . Asegura que los finalizadores en la base están garantizados para ejecutarse, pero es idéntico a anular la función Finalize . Esto significa que cuando escribe la syntax del destructor, realmente está escribiendo el finalizador.

Según Microsoft , el finalizador se refiere a la función que el recolector de basura llama cuando recolecta ( Finalize ), mientras que el destructor es tu bit de código que se ejecuta como resultado (el azúcar sintáctico que se convierte en Finalize ). Están tan cerca de ser lo mismo que Microsoft nunca debería haber hecho la distinción.

El uso de Microsoft del término “destructor” de C ++ es engañoso, porque en C ++ se ejecuta en el mismo hilo tan pronto como el objeto se elimina o se saca de la stack, mientras que en C # se ejecuta en un hilo separado en otro momento.

Encontrado aquí: http://sanjaysainitech.blogspot.com/2007/06/difference-between-destructor-dispose.html

  1. Incinerador de basuras

    Son métodos especiales que contienen código de limpieza para el objeto. No puede llamarlos explícitamente en su código, ya que GC los llama implícitamente. En C # tienen el mismo nombre que el nombre de clase precedido por el signo ~ . Me gusta-

     Class MyClass { ~MyClass() { ..... } } 

    En VB.NET, los destructores se implementan anulando el método Finalizar de la clase System.Object.

  2. Disponer

    Estos son como cualquier otro método en la clase y se pueden llamar explícitamente, pero tienen un propósito especial de limpiar el objeto. En el método de eliminación, escribimos un código de limpieza para el objeto. Es importante que liberemos todos los recursos no administrados en el método de disposición como conexión de base de datos, archivos, etc. El método de disposición de implementación de clase debe implementar una interfaz IDisposable. Un método de eliminación debe llamar al método GC.SuppressFinalize para el objeto que está desechando si el class tiene un desturctor porque ya ha hecho el trabajo de limpiar el objeto, entonces no es necesario que el recolector de basura llame al método Finalize del objeto. Referencia: http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

  3. Finalizar

    Un método Finalize actúa como una salvaguarda para limpiar los recursos en caso de que no se llame a su método Dispose. Solo debe implementar un método Finalize para limpiar recursos no administrados. No debe implementar un método Finalize para objetos administrados, ya que el recolector de basura limpia los recursos administrados automáticamente. El GC llama implícitamente el método de finalización, por lo tanto, no puede llamarlo desde su código.

    Nota: En C #, el método Finalize no puede anularse, por lo que debe usar el destructor cuya implementación interna anulará el método Finalize en MSIL. Pero en el método VB.NET, Finalize se puede anular porque admite el método destructor.

Actualización: hilo semi relacionado relacionado aquí .