¿Qué significa la tilde antes del nombre de una función en C #?

164

Estoy mirando un código y tiene esta declaración:

~ConnectionManager()
{
    Dispose(false);
}

La clase implementa la IDisposableinterfaz, pero no sé si eso es parte de eso para lo que se usa la tilde (~).

Keith Sirmons
fuente

Respuestas:

213

~ es el destructor

  1. Los destructores se invocan automáticamente y no se pueden invocar explícitamente.
  2. Los destructores no se pueden sobrecargar. Por lo tanto, una clase puede tener, como máximo, un destructor.
  3. Los destructores no son heredados. Por lo tanto, una clase no tiene destructores que no sean el que se puede declarar en ella.
  4. Los destructores no se pueden usar con estructuras. Solo se usan con clases. Una instancia se vuelve elegible para la destrucción cuando ya no es posible que ningún código use la instancia.
  5. La ejecución del destructor para la instancia puede ocurrir en cualquier momento después de que la instancia sea elegible para la destrucción.
  6. Cuando se destruye una instancia, los destructores en su cadena de herencia se llaman, en orden, de más derivados a menos derivados.

Finalizar

En C #, el método Finalize realiza las operaciones que haría un destructor C ++ estándar. En C #, no lo nombra Finalizar: utiliza la sintaxis del destructor de C ++ para colocar un símbolo de tilde (~) antes del nombre de la clase.

Disponer

Es preferible disponer de objetos en un método Close()o Dispose()que pueda ser llamado explícitamente por el usuario de la clase. Finalize (destructor) son llamados por el GC.

La interfaz IDisposable le dice al mundo que su clase retiene recursos que necesitan ser eliminados y proporciona a los usuarios una forma de liberarlos. Si necesita implementar un finalizador en su clase, su método Dispose debe usar el GC.SuppressFinalize()método para garantizar que se suprima la finalización de su instancia.

¿Qué usar?

No es legal llamar a un destructor explícitamente. Su recolector será llamado por el recolector de basura. Si maneja valiosos recursos no administrados (como los manejadores de archivos) que desea cerrar y desechar lo más rápido posible, debe implementar la interfaz IDisposable.

Patrick Desjardins
fuente
3
No sé cómo solía ser en el pasado. Pero ahora los destructores son heredados. Consulte este enlace para obtener más información (consulte el ejemplo al final): msdn.microsoft.com/en-us/library/66x5fx1b.aspx
RononDex
1
@RononDex, punto 3 de la misma página a la que enlaza, dice "Los finalizadores no se pueden heredar" , lo que contradice su comentario. Es cierto que es un poco confuso porque, aunque no se pueden heredar, "el Finalizemétodo se llama de forma recursiva para todas las instancias de la cadena de herencia, desde la más derivada hasta la menos derivada" . Sin embargo, tenga en cuenta que ese no es el mismo comportamiento que obtendría de los destructores heredables.
Mark Amery
@ MarkAmery ah, ya veo, ¿entonces básicamente se les llama en orden inverso en comparación con algo que se hereda?
RononDex
45

Este es un finalizador . Para ser honesto, rara vez necesitará escribir un finalizador. Realmente solo necesitas escribir uno si:

  • Tiene acceso directo a un recurso no administrado (por ejemplo, a través de un IntPtr) y no puede usarlo, SafeHandlelo que lo hace más fácil.
  • Está implementando IDisposableen una clase que no está sellada. (Prefiero sellar clases a menos que estén diseñadas para herencia). Un finalizador es parte del patrón de eliminación canónico en tales casos.
Jon Skeet
fuente
9

Se utiliza para indicar el destructor para la clase.

torial
fuente
12
Ambos son correctos, según la especificación de C # que leas. El más reciente de MS (C # 3.0 unificado) se refiere a ellos como destructores (por ejemplo, la sección 10.13) pero la especificación ECMA se refiere a ellos como finalizadores.
Jon Skeet
@ 1800INFORMATION: El elemento sintáctico se denomina correctamente destructor. Si una clase tiene un destructor, un compilador de C # generará automáticamente un finalizador que incluye un try/finallybloque generalmente inútil que garantiza que Finalizese llame al método padre . La mayoría de las cosas que son ciertas para los destructores son verdaderas para los finalizadores, y viceversa, pero las palabras significan cosas ligeramente diferentes.
supercat
4

Igual que C ++, es el destructor; sin embargo, en C # no lo llama explícitamente, se invoca cuando se recolecta el objeto.

Santiago Palladino
fuente
3

Consulte Destructores (Guía de programación de C #) . Sin embargo, tenga en cuenta que, a diferencia de C ++, el programador no tiene control sobre cuándo se llama al destructor porque esto lo determina el recolector de basura.

Jeff Stong
fuente