Esta documentación está archivada y no tiene mantenimiento.

Destructores (Guía de programación de C#)

Los destructores se utilizan para destruir instancias de clases.

  • Los destructores no se pueden definir en estructuras. Sólo se utilizan con clases.

  • Una clase sólo puede tener un destructor.

  • Los destructores no se pueden heredar ni sobrecargar.

  • No se puede llamar a los destructores. Se invocan automáticamente.

  • Un destructor no permite modificadores de acceso ni tiene parámetros.

Por ejemplo, el siguiente código muestra una declaración de un destructor para la clase Car:

class Car
{
    ~ Car()  // destructor
    {
        // cleanup statements...
    }
}

El destructor llama implícitamente al método Finalize en la case base del objeto. Por lo tanto, el código de destructor anterior se traduce implícitamente a:

protected override void Finalize()
{
    try
    {
        // cleanup statements...
    }
    finally
    {
        base.Finalize();
    }
}

Esto significa que se llama al método Finalize de forma recursiva para todas las instancias de la cadena de herencia, desde la más derivada hasta la menos derivada.

NoteNota

No se deben utilizar destructores vacíos. Cuando una clase contiene un destructor, se crea una entrada en la cola Finalize. Cuando se llama al destructor, se invoca al recolector de elementos no utilizados para procesar la cola. Si el destructor está vacío, simplemente se produce una pérdida de rendimiento innecesaria.

El programador no puede controlar cuándo se llama al destructor, porque esto lo determina el recolector de elementos no utilizados. El recolector de elementos no utilizados comprueba si hay objetos que ya no están siendo utilizados por ninguna aplicación. Si considera un objeto elegible para su destrucción, llama al destructor (si existe) y reclama la memoria utilizada para almacenar el objeto. También se llama a los destructores cuando se cierra el programa.

Es posible forzar la recolección de elementos no utilizados llamando al método Collect, pero en la mayoría de los casos debe evitarse su uso por razones de rendimiento. Para obtener más información, vea Forzar una recolección de elementos no utilizados.

En general, C# no requiere tanta administración de memoria como se necesita al desarrollar con un lenguaje que no está diseñado para un motor en tiempo de ejecución con recolección de elementos no utilizados. Esto es debido a que el recolector de elementos no utilizados de .NET Framework administra implícitamente la asignación y liberación de memoria para los objetos. Sin embargo, cuando la aplicación encapsule recursos no administrados como ventanas, archivos y conexiones de red, debería utilizar destructores para liberar dichos recursos. Cuando el objeto se marca para su destrucción, el recolector de elementos no utilizados ejecuta el método Finalize.

Si la aplicación utiliza un recurso externo caro, también es recomendable liberar explícitamente el recurso antes de que el recolector de elementos utilizados libere el objeto. Para ello debe implementar un método Dispose desde la interfaz IDisposable que realiza la limpieza del objeto necesaria. Esto puede mejorar considerablemente el rendimiento de la aplicación. Aunque controle explícitamente los recursos, el destructor garantiza la liberación de recursos si falla la llamada al método Dispose.

Para obtener más detalles sobre la liberación de recursos, vea los siguientes temas:

En el siguiente ejemplo se crean tres clases que forman una cadena de herencia. La clase First es la clase base, Second se deriva de First y Third se deriva de Second. Las tres tienen destructores. En Main(), se crea una instancia de la clase más derivada. Cuando ejecute el programa, observe que se llama a los destructores de las tres clases automáticamente y en orden, desde la más derivada hasta la menos derivada.

class First
{
    ~First()
    {
        System.Console.WriteLine("First's destructor is called");
    }
}

class Second: First
{
    ~Second()
    {
        System.Console.WriteLine("Second's destructor is called");
    }
}

class Third: Second
{
    ~Third()
    {
        System.Console.WriteLine("Third's destructor is called");
    }
}

class TestDestructors
{
    static void Main() 
    {
        Third t = new Third();
    }
}

Third's destructor is called

Second's destructor is called

First's destructor is called

Para obtener más información, vea las secciones siguientes de Especificación del lenguaje C#.

  • 1.6.6.6 Destructores

  • 10.2.7.4 Nombres de miembros reservados para destructores

  • 10.12 Destructores (Clases)

  • 11.3.9 Destructores (Estructuras)

Mostrar: