InicioArticulos y noticiasBases de datosProgramaciónForosInternetServiciosContratacionEmail
Tutorial C#
Introduccion a C#
Programacion con C#
Fundamentos de C#
Operadores
Instrucciones
Estrcuturas de control.
Definición de clases
Creación de objetos
Herencia y métodos virtuales
Polimorfismo
Ocultación de miembros
Miembros de tipo
Encapsulación
Espacios de nombres
Importación de espacios de nombres
Espacio de nombres distribuidos
Variables y tipos de datos
Tablas unidimensionales
Tablas multidimensionales
La clase System.Array
Cadenas de texto
Constantes
Orden de inicialización de variables
Métodos
Métodos externos
Constructores
Destructores
Propiedades
Indizadores
Redefinición de operadores
Delegados y eventos
La clase MulticastDelegate
Llamadas asíncronas
Implementación interna de los delegados
Eventos
Estructuras
Boxing y unboxing
Constructores de estructuras
Enumeraciones
Interfaces
Excepciones
Otras instrucciones
Atributos
Definición de nuevos atributos
Lectura de atributos en tiempo de ejecución
Atributos de compilación
Pseudoatributos
Código inseguro
Definición de punteros
Manipulación de punteros
Operadores relacionados con código inseguro
Fijación de variables apuntadas
Novedades de C# 2.0
Genéricos
Tipos parciales
Iteradores
Mejoras en la manipulación de delegados
Tipos anulables
Modificadores de visibilidad de bloques get y set
Clases estáticas
Referencias a espacios de nombres
Supresión temporal de avisos
Atributos condicionales
Incrustación de tablas en estructuras
Modificaciones en el compilador
También puedes ver ...
TransactionScope - Simplificando el trabajo con transacciones.
LinQ To SQL - Un ejemplo sencillo
Cómo activar Intelisense (autocompletado) en el Web.config
Leer un campo XML de SQL Server 2005 con C#
TripleDES - Un ejemplo practico en C#
Mostrar un GridView dentro de un DataList
String.Format
Métodos Extensores: INNER JOIN
Problemas en la instalación de Visual Studio 2008-Visual studio web authoring component
Redimiento de VS2008

Afiliados
La Web del programador
MundoProgramacion


 

Destructores

    Al igual que es posible definir métodos constructores que incluyan código que gestione la creación de objetos de un tipo de dato, también es posible definir un destructor que gestione cómo se destruyen los objetos de ese tipo de dato. Este método suele ser útil para liberar recursos tales como los ficheros o las conexiones de redes abiertas que el objeto a destruir estuviese acaparando en el momento en que se fuese a destruir.

    La destrucción de un objeto es realizada por el recolector de basura cuando realiza una  recolección de basura  y detecta que no existen referencias a ese objeto ni en pila, ni en registros ni desde otros objetos sí referenciados. Las recolecciones se inician automáticamente cuando el recolector detecta que queda poca memoria libre o que se va a finalizar la ejecución de la aplicación, aunque también puede forzarse llamando al método Collect() de la clase System.GC

    La sintaxis que se usa para definir un destructor es la siguiente:


~<nombreTipo>()
{
 <código>
}

    Tras la ejecución del destructor de un objeto de un determinado tipo siempre se llama al destructor de su tipo padre, formándose así una cadena de llamadas a destructores que acaba al llegarse al destructor de object. Éste último destructor no contiene código alguno, y dado que object no tiene padre, tampoco llama a ningún otro destructor.

    Los destructores no se heredan. Sin embargo, para asegurar que la cadena de llamadas a destructores funcione correctamente si no incluimos ninguna definición de destructor en un tipo, el compilador introducirá en esos casos una por nosotros de la siguiente forma:


~<nombreTipo>()
{}

    El siguiente ejemplo muestra como se definen destructores y cómo funciona la cadena de llamada a destructores:


using System;
class A
{
 ~A()
 {
  Console.WriteLine("Destruido objeto de clase A");
 }
}
class B:A
{
 ~B()
 {          
  Console.WriteLine("Destruido objeto de clase B");
 }
 public static void Main()
 {
  new B();
 }
}

    El código del método Main() de este programa crea un objeto de clase B pero no almacena ninguna referencia al mismo. Luego finaliza la ejecución del programa, lo que provoca la actuación del recolector de basura y la destrucción del objeto creado llamando antes a su destructor. La salida que ofrece por pantalla el programa demuestra que tras llamar al destructor de B se llama al de su clase padre, ya que es:



Destruido objeto de clase B

Destruido objeto de clase A

 

    Nótese que aunque no se haya guardado ninguna referencia al objeto de tipo B creado y por tanto sea inaccesible para el programador, al recolector de basura no le pasa lo mismo y siempre tiene acceso a los objetos, aunque sean inútiles para el programador.

    Es importante recalcar que no es válido incluir ningún modificador en la definición de un destructor, ni siquiera modificadores de acceso, ya que como nunca se le puede llamar explícitamente no tiene ningún nivel de acceso para el programador. Sin embargo, ello no implica que cuando se les llame no se tenga en cuenta el verdadero tipo de los objetos a destruir, como demuestra el siguiente ejemplo:


using System;
public class Base
{
 public virtual void F()
 {
  Console.WriteLine("Base.F");               
 }
 
 ~Base()
 {
  Console.WriteLine("Destructor de Base");
  this.F();
 }
}
public class Derivada:Base
{
 ~Derivada()
 {
  Console.WriteLine("Destructor de Derivada");
 }
 
 public override void F()
 {
  Console.WriteLine("Derivada.F()");
 }
 
 public static void Main()
 {
  Base b = new Derivada();                      
 }
}

    La salida mostrada que muestra por pantalla este programa al ejecutarlo es:


Destructor de Derivada

Destructor de Base

Derivada.F()

    Como se ve, aunque el objeto creado se almacene en una variable de tipo Base, su verdadero tipo es Derivada y por ello se llama al destructor de esta clase al destruirlo. Tras ejecutarse dicho destructor se llama al destructor de su clase padre siguiéndose la cadena de llamadas a destructores. En este constructor padre hay una llamada al método virtual F(), que como nuevamente el objeto que se está destruyendo es de tipo Derivada, la versión de F() a la que se llamará es a la de la dicha clase.

    Nótese que una llamada a un método virtual dentro de un destructor como la que se hace en el ejemplo anterior puede dar lugar a errores difíciles de detectar, pues cuando se llama al método virtual ya se ha destruido la parte del objeto correspondiente al tipo donde se definió el método ejecutado. Así, en el ejemplo anterior se ha ejecutado Derivada.F() tras Derivada.~F(), por lo que si en Derivada.F() se usase algún campo destruido en Derivada.~F() podrían producirse errores difíciles de detectar.


Inicio | Tutorial C# ConstructoresTutorial C#Propiedades Versión para imprimir Foros de consulta


Añadir comentario ... Para preguntar utiliza los foros
Autor:

Título:


Para preguntar utiliza los foros.



Inicio | Tutorial C# ConstructoresTutorial C#Propiedades Versión para imprimir

Destructores
Autor: José Antonio González Seco
Visitas: 6904 Fecha de publicación: 13/10/2006
José Antonio es experto en tecnologias Microsoft. Imparte cursos y conferencias en congresos sobre C# y .NET en Universidades de toda España (Sevilla, Barcelona, San Sebastián, Valencia, Oviedo, etc.) en representación de grandes empresas como Microsoft.




18/08/2008 SQL Server 2008
Visitas: 39 | Comentarios: 0 | Archivo: Articulos
Categorias: Transact-SQL
Visitas: 131 | Comentarios: 0 | Archivo: Articulos
Categorias: C#|ADO.NET|LinQ
Visitas: 161 | Comentarios: 1 | Archivo: Articulos
Categorias: Humor
Visitas: 154 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 123 | Comentarios: 0 | Archivo: Articulos
Categorias: WCF
Visitas: 210 | Comentarios: 0 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 278 | Comentarios: 5 | Archivo: Articulos
Categorias: ASP.NET
Visitas: 4990 | Comentarios: 4 | Archivo: Articulos
Categorias: C#|Transact-SQL|LinQ
Visitas: 602 | Comentarios: 1 | Archivo: Articulos
Categorias: Visual Studio
Visitas: 1402 | Comentarios: 1 | Archivo: Articulos
Categorias: Transact-SQL

Útimos temas recibidos en los foros ...
Y lo mismo en WEB por systemat ... [C#] 1 18/08/2008
Manual del minicom de Linux con fotos. por Meta ... [UNIX] 4 17/08/2008
PROGRAMACION por JUANMA ... [Visual Basic .NET] 1 19/08/2008
Conectar ASP con B.D Informix por Franco ... [ASP] 9 02/05/2007
Codigo salir por Jazmin ... [ASP.NET] 1 18/08/2008
EXPORTAR DATOS A ARCHIVOS PLANOS. por WIX ... [ORACLE] 10 06/08/2007
formulario por artdark ... [C#] 2 04/08/2008
Codigo salir por Jazmin ... [ASP.NET] 0 18/08/2008
cambiar de modo un gried view por ivan ... [ASP.NET] 0 18/08/2008
ayuda urgente porfavor por vicancer ... [ASP.NET] 0 18/08/2008
pollo por hajaj ... [Actualidad] 1 15/08/2008
DIOS TE BENDIGA por El You ... [WIN 98/NT/2000/XP] 1 16/08/2008

Access CGI JSP ORACLE UNIX
Actualidad HTML/DHTML/XHTML LINUX PHP Visual Basic .NET
ASP ISAPI MS DOS Power Builder Visual Basic 6.0
ASP.NET Java mySQL SQL WIN 98/NT/2000/XP
C# JavaScript Opinion SQL Server

devjoker  Te recomendamos además ...
28/06/2006 Triggers en PL/SQL    forma parte de...Tutorial PL/SQL
07/11/2006 Enumeraciones    forma parte de...Tutorial C#
28/06/2006 Excepciones en PL/SQL    forma parte de...Tutorial PL/SQL
22/10/2005 Insertar datos. INSERT    forma parte de...Tutorial SQL
22/04/2008 TripleDES - Un ejemplo practico en C#
16/11/2005 Delegados en C#
18/10/2005 Enviar emails a través de un servidor SMTP autenticado con Java
19/08/2006 Vitualización. Maquinas Virtuales.
23/12/2007 Primeras impresiones sobre Visual Studio 2008
22/10/2005 El lenguaje SQL    forma parte de...Tutorial SQL

 

Encuesta
Si trabajas con .NET ¿Que entorno utilizas?
[Ver] [Votar]