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

Recientemente he descubierto que Visual Studio 2008 considera un destructor sinónimo de un método Finalize, lo que significa que Visual Studio no permiten que a la vez definen 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 para Finalizar en el destructor:

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

Y si la llamada para Finalizar se comenta, se da el siguiente error:

Tipo ‘ManagementConcepts.Servicio.TestFinalize’ ya define un miembro de la llamada
‘Finalizar’ con los mismos tipos de parámetros

InformationsquelleAutor Jeff Leonard | 2009-07-02

3 Comentarios

  1. 62

    Un destructor en C# anula System.Object.Finalize método. Usted tiene que uso destructor sintaxis para hacerlo. Reemplazar manualmente Finalize le dará un mensaje de error.

    Básicamente lo que están tratando de hacer con su Finalize declaración de método es ocultar el método de la clase base. Esto hará que el compilador emitirá una advertencia de que se puede silenciar utilizando el new modificador (si es que iba a funcionar). Lo importante a destacar aquí es que usted no puede tanto override y declarar un new miembro con el mismo nombre, al mismo tiempo, por lo que tener un destructor y un Finalize método, se producirá un error (pero puede, aunque no se recomienda, declarar un public new void Finalize() método si no estás declarando un destructor).

  2. 65

    Wikipedia tiene algunas buenas debate sobre la diferencia entre un finalizador y un destructor en el finalizador artículo.

    C# no tiene realmente un «verdadero» destructor. La sintaxis similar a C++ destructor, pero realmente es un finalizador. Escribiste correctamente en la primera parte de su ejemplo:

    ~ClassName() { }

    El de arriba es azúcar sintáctico para una Finalize función. Se asegura de que los finalizadores en la base están garantizados para correr, pero por lo demás es idéntica a la sustitución de la Finalize función. Esto significa que cuando usted escribe el destructor de la sintaxis, realmente estás escribiendo el finalizador.

    Según Microsoft, el finalizador se refiere a la función que el recolector de basura de llamadas cuando se acumula (Finalize), mientras que el destructor es su bits de código que se ejecuta como un resultado (el azúcar sintáctico que se convierte en Finalize). Ellos están tan cerca de ser la misma cosa que Microsoft debería haber nunca se hizo la distinción.

    De Microsoft, el uso de C++’s «destructor» término es engañoso, ya que en C++ se ejecuta en el mismo hilo tan pronto como se elimina el objeto o extraen la pila, mientras que en C# se ejecuta en un hilo separado en otro momento.

    • Yo diría que esa distinción entre el destructor y finalizador es uno de los más importantes para hacer. Sin embargo, sólo aquellos que se preocupan por lo que está pasando debajo de la capucha le importa dijo distinción.
    • También tenga en cuenta ECMA-334 explícitamente ha ambiguas «destructor» y «finalizador» formalmente, hace mucho tiempo. No sé por qué MS todavía insiste en el término engañoso en sus especificaciones.
    • Al menos desde el trabajo con Mono, C# es en realidad modelada después de C++, y la mayoría de los nativos de C# objetos son objetos de C++. La forma en que el compilador compila Mono obras dicta cómo los objetos de C++ son destruidas, y de la misma manera, ¿cómo C# objeto finalización se propaga a C++ y llama a los destructores. La distinción tiene sentido bajo el capó, pero todavía realmente no se aplican a C# sí mismo.
  3. 19

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

    1. Destructor

      Son métodos especiales que contiene el código de limpieza para el objeto.
      No se puede llamar de forma explícita en el código, como se llaman
      implícitamente por la GC. En C# que tener el mismo nombre que el nombre de la clase precedido
      por el ~ signo. Como

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

      En VB.NET, los destructores se implementan reemplazando al Finalizar
      método del Sistema.Clase de objeto.

    2. Disponer

      Estos son como cualquier otros métodos en la clase, y puede ser llamado
      explícitamente, pero que tiene una finalidad especial de limpieza en el objeto.
      En el método dispose podemos escribir el código de limpieza para el objeto. Es
      es importante que nos libera todos los recursos, entonces no administrado en el dispose
      método como la conexión de base de datos, archivos, etc. La clase que implementa
      método dispose debe implementar la interfaz IDisposable.Un método Dispose
      debe llamar a la GC.SuppressFinalize método del objeto es
      desechar si la clase tiene desturctor porque ya lo ha hecho el
      trabajo para limpiar el objeto, entonces no es necesario para la basura
      colector para llamar al objeto del método Finalize. Referencia:
      http://msdn2.microsoft.com/en-us/library/aa720161(VS.71).aspx

    3. Finalizar

      Un método Finalize actúa como una salvaguardia para limpiar los recursos en el
      caso de que su método Dispose no es llamado. Sólo debe
      implementar un método Finalize para limpiar los recursos no administrados. Usted
      no debe implementar un método Finalize para objetos administrados, porque
      el recolector de basura limpia recursos administrados de forma automática.
      Finalizar método es llamado por el GC implícitamente, por tanto, no se puede
      la llamada de su código.

      Nota: En C#, Finalizar método no se puede reemplazar, así que tienes que
      uso destructor cuya implementación interna anulará la
      Método Finalize en MSIL.Pero en el VB.NET Finalizar método puede ser
      reemplazar porque no admite método destructor.

    Actualización: Muy interesante, semi-relacionadas con el hilo aquí.

    • You should only implement a Finalize method to clean up unmanaged resources : se pone en Finalizar. Mismo con Deseche ?
    • Los casos donde se debe implementar Dispose muy superan en número a aquellos donde se debe implementar un finalizador. Implementar Dispose si es probable que una instancia de la clase o de una clase derivada será la última cosa que sea directamente el propietario de un recurso no administrado, o directamente el propietario de la última cosa directamente el propietario de un recurso no administrado, o directamente el propietario de la última cosa directamente propia, etc. Sólo implementar Finalize de los recursos de la limpieza si la clase de <i>directamente</i> el propietario de un recurso no administrado <i>y casi nada más</i>–una mucho más estrecho escenario.
    • Si una clase está directamente propios recursos no administrados y también contiene referencias a otros objetos, los recursos no administrados en general, debe ser dividido en sus propias finalizable clase (que debería, idealmente, que no tienen ningún fuertes referencias a cualquier otra cosa), es decir, la clase que contiene referencias a otros objetos sería solamente «cosas que directamente propios recursos no administrados», en lugar de ser dueño de los propios recursos, y por lo tanto no necesita un finalizador.

Dejar respuesta

Please enter your comment!
Please enter your name here