PDF de programación - Curso de C# - artículo 6

Imágen de pdf Curso de C# - artículo 6

Curso de C# - artículo 6gráfica de visualizaciones

Actualizado el 21 de Marzo del 2018 (Publicado el 31 de Enero del 2018)
650 visualizaciones desde el 31 de Enero del 2018
214,7 KB
6 paginas
Creado hace 16a (20/12/2007)
Este mes vamos a destruir (en el buen sentido) y también vamos a hacer de basureros recogiendo la basura. El estudio de
los métodos será nuestro próximo paso.

Curso de C#

Para empezar veremos los destructores, los cuales nos permitirán destruir una instancia de una clase. Para continuar,
explicaremos la sobrecarga de operadores y finalmente estudiaremos el paso de parámetros variables. En los ejemplos de
programación, construiremos un pequeño servidor que escuchará por un puerto las peticiones de programas clientes.

En el artículo del mes pasado estudiamos, entre otras cosas, los métodos constructores de las clases. Pues bien ahora veremos el
método opuesto: los destructores. Como ya dijimos (si no recuerdo mal) en la primera entrega, también hablaremos del
"recolector de basura" o Garbage Collector y lo invocaremos nosotros mismos a pesar de que es un proceso automatizado.

Hasta ahora, hemos creado objetos mediante new y no nos hemos preocupado de la memoria que utilizaban esos objetos. Esta
asignación dinámica de memoria necesita de un sistema de recuperación de la memoria libre dejada por los objetos que ya no se
utilizan. En C++ creo recordar que se utiliza el operador delete, en C# se utiliza el método de recolección de elementos no
utilizados. Este método (ó sistema. No confundir con método de una clase, por favor) lo que hace es recopilar objetos, de forma
transparente al usuario y en segundo plano, que ya no se puedan utilizar. ¿Cómo se sabe si un objeto ya no se puede utilizar?. Pues
fácil: si ya no hay ninguna referencia al objeto, se da por hecho que el objeto ya no se necesita y pasa a ser candidato a la
recolección. La recolección de basura se hace por parte del sistema y no porque los objetos pasen a ser candidatos a la
recolección. Tampoco es algo aleatorio. Debido a que la recolección requiere un tiempo, sólo se hace cuando es necesario o en
cualquier otro momento oportuno. Es decir: no podemos saber cuando tendrá lugar a no ser que lo “forcemos” nosotros, y aún así
tampoco sabremos en qué momento preciso se destruirá un objeto específico. Forzar la recolección sólo lo haremos para ilustrar
el funcionamiento de los destructores (enseguida vemos un ejemplo) ya que es absurdo hacer “perder” el tiempo al sistema si no
es necesario, y si lo es, ya lo hace él solito.

Destructores..
Un destructor es un método (miembro) de una clase que incluye las acciones necesarias o requeridas por la aplicación para
destruir un objeto o instancia de la clase a la que pertenece. Se le llama inmediatamente antes de que el recolector de elementos
no utilizados haya destruido el objeto. El método destructor se utiliza para asegurar que el objeto finaliza de forma correcta, es
decir, que realiza las acciones necesarias antes de destruirse. Imaginad un objeto que abra un archivo y lo maneje. Es conveniente
asegurarse de que antes de su destrucción, el archivo sea cerrado. Estas acciones son las que podríamos poner en el destructor.
Como ya hemos dicho antes, no basta con que un objeto deje de ser referenciado para que se invoque su destructor (a diferencia
de C++) sino que serán llamados cuando se efectúe la recolección o, simplemente, antes de finalizar el programa.

Sintácticamente, un destructor se especifica con el mismo nombre de la clase, pero precedido del símbolo ~. Si no lo hacemos así,
obtendremos un error en tiempo de compilación. Por ejemplo, si tenemos una clase llamada "revista", su destructor debe llamarse
"~revista" (recordad del mes pasado que su constructor se llamará "revista").
Muy importante: los destructores no se heredan, por lo que una clase tendrá únicamente el destructor que se defina en ella misma.
Otra cosa es que si una clase hereda de otra, los destructores se invoquen en un orden determinado. ¿Adivináis cual?. Lo podemos
comprobar con el listado del Listado 1. La salida de este programa es:

Se destruye el objeto de la clase hija
Se destruye el objeto de la clase madre

Os pongo así la salida ya que la clase GC (Garbage Collector) no está implementada aún en mono, por lo que no puedo ejecutarlo
en mi Linux. De todas formas, expliquemos el funcionamiento: Tenemos dos clases, la clase madre y la clase hija. Ésta última
hereda de la clase madre. En la clase principal, creamos un objeto de la clase hija, para después dejarlo inútil (lo igualamos a
null). Finalmente llamamos a los métodos Collect() y WaitForPendingFinalizers(). El primero inicia la recolección de elementos
no utilizados (¿os acordáis de cuando dijimos que invocaríamos al recolector de basura?, pues llegó el momento) y el segundo
detiene la ejecución del proceso hasta que se hayan invocado todos los destructores necesarios.

Los métodos más interesantes definidos en GC los podemos ver a continuación:
public static void Collect(): Comienza la recolección de elementos no utilizados.
public static void Collect(int Maximo): Comienza la recolección de elementos no utilizados de la memoria con números
iniciales comprendidos entre 0 y Maximo.
public static long GetTotalMemory(bool recopilados): Devuelve el número total de bytes asignados. Si “recopilados” es true,
se producirá la recopilación de elementos no utilizados en primer lugar.
public static void KeepAlive(object o): Crea una referencia al objeto o, evitando que sea candidato a la recopilación.
public static void WaitForPendingFinalizers(): Detiene la ejecución del proceso hasta que se hayan invocado todos los
destructores.

Un método destructor no puede tener parámetros (esto es muy importante también), por lo que no se puede sobrecargar. Llegados
a este punto es el momento de hablar ya de la sobrecarga de métodos.

Sobrecarga de métodos.
En la entrega anterior ya vimos cómo sobrecargar métodos. Lo utilizamos en una clase para definir un punto en el espacio
bidimensional. Si no le pasábamos ningún parámetro, se ejecutaba el constructor sin parámetros, que inicializaba las corrdenadas
a cero. Si le pasábamos las coordenadas, estos valores eran asumidos por el objeto al ejecutarse el constructor con parámetros.

Dos o más métodos de la misma clase pueden tener el mismo nombre si, y sólo si, sus parámetros son diferentes. Entonces
decimos que el método está sobrecargado. En definitiva, se trata de definir un método con distintos tipos ó número de parámetros,
para utilizarlo según nuestra conveniencia. El compilador decidirá cual ha de usar. También pueden devolver distintos tipos de
datos, aunque esto no es obligatorio, a diferencia de la condición anterior en cuanto a número o diferencia de tipos en los
parámetros. Hay que tener en cuenta que un tipo de datos devuelto no es suficiente para poder elegir el método a utilizar
(recordemos las conversiones implícitas, sin ir más lejos). Si llamamos a un método sobrecargado, se ejecutará aquel que coincida
en sus parámetros (tipos y número) con los argumentos proporcionados por nosotros.
Vamos a fijarnos en el Listado 2. Tenemos en nuestra clase, tres métodos con el mismo nombre “mensaje” y diferentes
parámetros. No devuelven ningún valor y son estáticos por motivos evidentes: los vamos a usar como funciones normales y no
queremos crear ningún objeto. Daros cuenta que en el primer método sólo tenemos un parámetro llamado texto. En el segundo ya
tenemos dos (titulo y texto, los dos string) y en el tercero tenemos dos parámetros, pero el primero es un entero. Con esto hemos
querido implementar un método para escribir mensajes en nuestro programa, pero con la flexibilidad de mandar distintos tipos de
argumentos según queramos en cada momento: escribir un texto, dar un aviso ó mandar un mensaje de error con su código.

Figura1

Viendo el resultado de la ejecución del programa (Figura 1) comprobamos que, efectivamente, el compilador ha hecho su trabajo:
Para cada llamada al método, ha elegido el que le correspondía (¿acaso lo dudabais? jejejeje).
La sobrecarga de métodos es una de las formas que se utiliza en C# para implementar el polimorfismo, ya que de esta forma se
cumple con el paradigma “una interfaz, varios métodos”. El ejemplo más clarificador si lo comparamos con C es el de la función
Abs que devuelve el valor absoluto. En C no se permite la sobrecarga, por lo que para obtener el valor absoluto existen varias
funciones (abs(), labs(), fabs()...) dependiendo del tipo de datos del argumento. Es un “obstáculo” para el programador y un
“atraso” conceptual el tener varias funciones para lo mismo. Como ya sabemos, en la clase Math de C#, tenemos el método Abs()
que, podéis comprobar, se sobrecarga adecuadamente para manejar los distintos argumentos numéricos recibidos. La sobrecarga
además permite agrupar métodos relacionados con un nombre común a todos, permitiendo así simplificar el manejo de conceptos
complejos.

Para terminar con la sobrecarga, definiremos el concepto de firma. La firma de un método en C# es su nombre más la lista de
parámetros. Es evidente pues que, debido a la sobrecarga de operadores, dos métodos de la misma clase nunca podrán tener la
misma firma. Insisto en que el tipo devuelto por un método no es relevante para definir qué método sobrecargado utilizar. Por eso
no se incluye en la firma. Tampoco se incluye en la firma un paramétro “params”, por lo que no influye en la resolución de la
sobrecarga, a pesar de ser un parámetro, pero ¿qué es eso de un parámetro “params”?.

Uso de params como parámetro. Número variable de argumentos.
Cuando escribimos un método, normalmente sabemos el número de argumentos que va a recibir, pero no siempre es así.
Imaginemos que queremos escribir un método que devuelva el valor máximo de unos parámetros que reciba. Es evidente que
mediante el paso de parámetros típico estaríamos limitados. Nosotros queremos pasar un número indeterminado de ellos. Esto lo
hacemos mediante un parámetro “params”. Este es un modificador que nos permite declarar un parámetro array (tabla, matriz,
etc...) que puede recibir un nú
  • Links de descarga
http://lwp-l.com/pdf8551

Comentarios de: Curso de C# - artículo 6 (0)


No hay comentarios
 

Comentar...

Nombre
Correo (no se visualiza en la web)
Valoración
Comentarios...
CerrarCerrar
CerrarCerrar
Cerrar

Tienes que ser un usuario registrado para poder insertar imágenes, archivos y/o videos.

Puedes registrarte o validarte desde aquí.

Codigo
Negrita
Subrayado
Tachado
Cursiva
Insertar enlace
Imagen externa
Emoticon
Tabular
Centrar
Titulo
Linea
Disminuir
Aumentar
Vista preliminar
sonreir
dientes
lengua
guiño
enfadado
confundido
llorar
avergonzado
sorprendido
triste
sol
estrella
jarra
camara
taza de cafe
email
beso
bombilla
amor
mal
bien
Es necesario revisar y aceptar las políticas de privacidad