En Visual Basic, el constructor es un procedimiento Sub New que se llama al crear una instancia de una clase e inicializa el objeto. El destructor se implementa utilizando el método Finalize o la interfaz IDisposable (método Dispose), lo cual es especialmente importante para liberar recursos.
En el Visual Basic clásico, el constructor se llamaba automáticamente al crear objetos (Class_Initialize), y el destructor al eliminarlos (Class_Terminate). En VB.NET se han añadido constructores sobrecargables, la separación de la liberación de recursos administrados y no administrados, y el uso del recolector de basura (GC).
El uso incorrecto de constructores o destructores conduce a fugas de memoria, inicialización incorrecta de objetos o bloqueo de recursos (por ejemplo, archivos).
Utilice Sub New para inicializar objetos, e implemente Dispose para liberar explícitamente recursos. Si se utiliza un destructor (Finalize), recuerde la latencia del GC y la imposibilidad de predecir el momento de su llamada.
Ejemplo de código:
Public Class ResourceHolder Implements IDisposable Private resource As SomeResource Public Sub New() resource = New SomeResource() Console.WriteLine("Recurso asignado") End Sub Protected Overrides Sub Finalize() Dispose(False) MyBase.Finalize() End Sub Public Sub Dispose() Implements IDisposable.Dispose Dispose(True) GC.SuppressFinalize(Me) End Sub Protected Overridable Sub Dispose(disposing As Boolean) If disposing Then If resource IsNot Nothing Then resource.Release() resource = Nothing End If End If End Sub End Class
Características clave:
¿Se puede llamar manualmente al constructor Sub New de un objeto ya existente?
No, el constructor solo se llama al crear un objeto. Para reinicializar, use un método separado Reset o similar.
¿Cuándo se llama a Finalize y su ejecución siempre está garantizada?
Finalize se llama por el recolector de basura al destruir un objeto, pero su ejecución no está garantizada (por ejemplo, en caso de un cierre inesperado del proceso o una interrupción de energía).
¿Por qué es necesario llamar a GC.SuppressFinalize dentro de Dispose?
Esto previene la llamada repetida a Finalize para un objeto que ya ha sido liberado manualmente, mejorando el rendimiento y evitando fugas de memoria.
En el proyecto no implementaron Dispose, y varios archivos permanecieron bloqueados después de que la aplicación terminó de ejecutarse: los recursos no se liberaron hasta la intervención del recolector de basura.
Pros:
Contras:
Implementaron IDisposable y Dispose, utilizaron Using al trabajar con recursos externos. Todos los archivos se cierran correctamente y la aplicación funciona de manera estable.
Pros:
Contras: