framework .net 3.5 05 tipo y jerarquía de objetos

17
Los tipos a los que se refiere CTS no son sólo aquellos utilizables al declarar una variable, en realidad incluyen todo aquello que se pueda instanciar en el código. Es decir, los tipos son realmente objetos, e incluyen todos los objetos utilizables en el código, con lo que el CTS da instrucciones al CLR para la gestión de todo tipo de objetos. Todos los tipos heredan de la clase base System.Object, por lo que los métodos y atributos de esta estarán disponibles en cualquier tipo que definamos. Los tipos se dividen en dos categorías principales: tipos por valor y tipos por referencia, los cuales se diferencian en la forma en la que se gestionan en memoria. Los tipos por valor se almacenan en la memoria rápida o pila (Stack), los tipos por referencia guardan en la pila la dirección de memoria lenta o montón (Heap) en la que realmente están situados los datos.

Upload: antonio-palomares-sender

Post on 17-Jul-2015

655 views

Category:

Technology


2 download

TRANSCRIPT

Los tipos a los que se refiere CTS no son sólo aquellosutilizables al declarar una variable, en realidad incluyen todoaquello que se pueda instanciar en el código.

Es decir, los tipos son realmente objetos, e incluyen todoslos objetos utilizables en el código, con lo que el CTS dainstrucciones al CLR para la gestión de todo tipo de objetos.

Todos los tipos heredan de la clase baseSystem.Object, por lo que los métodos y atributos de estaestarán disponibles en cualquier tipo que definamos.

Los tipos se dividen en dos categorías principales: tipos porvalor y tipos por referencia, los cuales se diferencian en laforma en la que se gestionan en memoria.

Los tipos por valor se almacenan en la memoria rápida opila (Stack), los tipos por referencia guardan en la pila ladirección de memoria lenta o montón (Heap) en la querealmente están situados los datos.

Esta diferenciación viene debida a que la memoria rápida noes muy grande, con lo que los datos ahí almacenados tienenuna limitación de tamaño. Por lo tanto los tipos por valorsiempre serán datos con poca ocupación de memoria, encambio los tipos por referencia pueden tener cualquiertamaño, no sufriendo de las mismas limitaciones.

Las variables de tipos por referencia pueden ser variasapuntando a la misma dirección de memoria, por lo que si seejecuta alguna modificación en los datos mediante una deellas, se estará afectando a todas ellas, por existir sólo unacopia de los datos.

Las variables de tipos por valor, en cambio, no sufren deéste problema, al tener, cada una de ellas, su propia copia delos datos.

El esquema de organización de los tipos en .NET Frameworkes el siguiente:

Tipos por referencia

Punteros

Interfaces

Auto-descritos Arrays o Matrices

Clases Clases del programador

Delegados

Embalados (Boxing)

Integrados o Nativos

Enumeraciones Definidos por el programador

Tipos por valor

Un ejemplo de utilización de variables de los dos tipos, paraque puedas apreciar las diferencias antes enumeradas:

class ClasePrueba

{

public int Valor = 0;

}

class Program

{

static void Main(string[] args)

{

int valorA = 0;

int valorB = valorA;

valorB = 999;

ClasePrueba refA = new ClasePrueba();

ClasePrueba refB = refA;

refB.Valor = 999;

Console.WriteLine("Val: {0}, {1}", valorA, valorB);

Console.WriteLine("Ref: {0}, {1}", refA.Valor, refB.Valor);

Console.ReadLine();

}

}

El resultado sería:Valores: 0, 999

Referencias: 999, 999

La definición de tipos por parte del programador esintrínseca al módulo en el que se realice, es decir, si definesdos tipos diferentes, pero con el mismo nombre, en diferentesmódulos de ejecución, el sistema los tratará como tiposdistintos y no habrá ningún problema.

Para definir un nuevo tipo siempre se partirá de un tipoexistente, aunque sólo sea System.Object, y será necesarioespecificar su contenido:

Su nombre, que ha de ser una cadena de caracteres.El tipo del que hereda, uno y sólo uno, ya que la herencia múltiple noestá soportada por el entorno. Como mínimo, System.Object, siningún otro tipo puede servirte de base para el que estés definiendo.Sus atributos, o Metadatos adicionales proporcionados por el usuario.Su visibilidad, public, protected, private, internal o assembly, yase verá más adelante en detalle.Las interfaces implementadas, sin limitación de número, pero deberánimplementarse todas las del tipo base o heredado.La definición de cada uno de sus miembros (eventos, campos, tiposanidados, métodos y propiedades), incluyendo su firma única.

static void Main(string[] args){

// Tipo por valorint Importe = 1500;// Embalaje - BOXING:object OtroImporte = Importe;/* Si cambiamos el tipo por valor, la variable Object mantiene el valor

original ya que los valores de ambas variables son copiasindependientes */

Importe = 999;/* Desembalaje - UNBOXING:

Crear un nuevo tipo por valor y asignarle el tipo Object */int NuevoImporte = (int)OtroImporte;Console.WriteLine("Valor: {0}, Referencia: {1}, Nuevo: {2}",

Importe, OtroImporte, NuevoImporte);Console.ReadLine();

}

Boxing (Embalaje) y Unboxing (desembalaje)La operación de Boxing o embalaje sólo se aplica a los tipos por

valor, consiste en la conversión de un tipo por valor a una variableObject almacenada en el Stack y una copia del tipo por valoralmacenado en el Heap, al que apuntará la nueva variable de tipoObject.

La operación opuesta Unboxing o desembalaje, consiste en pasarde un tipo Object a un tipo por valor.

Valor: 999, Referencia: 1500, Nuevo: 1500

Tipos por valor predefinidos más utilizados:

Aunque hay unos 300 más.

CTS C# DescripciónByte Byte Entero sin signo de 8 bitSByte sbyte Entero sin signo de 8 bit (tipo no acorde con el CLS)Int16 short Entero con signo de 16 bitInt32 int Entero con signo de 32 bitInt64 long Entero con signo de 64 bitSingle float Numero con coma flotante de precisión simple, de

32 bitDouble double Numero con coma flotante de precisión doble, de 64

bitBoolean bool Valor lógicoChar char Caracter Unicode de 16 bitDecimal decimal Valor decimal de 96 bitString string Cadena de caracteresUInt32 uint Enteros positivos, de 32 bitsDateTime Date Momentos en el tiempo (fechas y/u horas)

Tipos por referencia predefinidos más utilizados:

Aunque hay unos 2.500 más.

CTS C# DescripciónObject object El tipo más genérico de .NET, del

que derivan todos los demás, directa o indirectamente. Provee a todos los objetos de los métodos toString y equals, entre otros miembros.

String string Un array de caracteres, manipulado como un todo, para contener cadenas de texto.

StringBuilder stringBuilder Clase especializada en el manejo de cadenas de caracteres.

Array array Clase base para todos los tipos detablas, series, matrices, vectores, …

Stream stream Clase base para todos los tipos debuffers de entrada/salida.

Exception exception Para la gestión de errores.

Tipos genéricos:

Son la solución aportada para solventar los problemas deboxing y unboxing antes mencionados en el paso deparámetros a las clases, estructuras, interfaces y métodosque definamos, ya que permiten retrasar la definición deltipo concreto de dato a utilizar hasta la declaración einstanciación del objeto por parte del código cliente.

También nos permiten la definición de código nodependiente del tipo de dato, evitando la duplicidad declases con la única diferencia del tipo de datos recibidos y/odevueltos.

La sintaxis específica es la de nombreClase<T>, en la queT es el nombre del tipo de dato que deberá suministrarseen el momento de definir o crear el objeto.

El IntelliSense integrado en el IDE nos facilitará unavalidación inicial del uso de nuestras clases genéricas.

Se pueden especificar restricciones a los tipos de datos quese admitan como argumentos.

Nullable<bool> b = null;

bool? b = null;

if (b.HasValue)

Console.WriteLine("b is {0}.", b.Value);

else

Console.WriteLine("b is not set.");

Tipos nullables:

Son aquellos tipos por valor que pueden contener un valor

nulo (null).

Su sintaxis es Nullable<T> o T?

Using System.drawing;

// Creamos un punto

System.Drawing.Point p = new System.Drawing.Point(20, 30);

// Movemos el punto diagonalmente

p.Offset(-1, -1);

Console.WriteLine("Point X {0}, Y {1}", p.X, p.Y);

Tipos definidos por el usuario - Estructuras:Son tipos de dato por valor, con lo que contendrán

directamente sus valores, almacenándose en el stack, siendoesto lo que las diferencia de las clases.

Las estructuras se componen de otros tipos dedato, combinados para facilitar su manipulación.

Un ejemplo sencillo es System.Drawing.Point, la cualcontiene unas propiedades enteras, X e Y, que definen laposición horizontal y vertical de una coordenada espacial.

Esta estructura dispone también de un constructor y unosmiembros, para facilitar su utilización.

Para definir una estructura hemos de utilizar la palabraclave struct.

Las estructuras se pueden convertir de tipos por valor atipos por referencia cambiando esta palabra clave por class.

Aunque las estructuras suelen ser más eficientes que lasclases, siempre y cuando cumplan las siguientes condiciones:

Representen un valor lógico único.

El tamaño de instancia no sea superior a 16 bytes.

Que no cambie frecuentemente después de la creación.

Que no se transforme a tipo por referencia mediantecasting.

Tipos definidos por el usuario - Enumeraciones:Las enumeraciones son tipos que podemos definir para

almacenar listas de valores fijos relacionados.Los valores almacenados serán una lista de

enteros, aunque nos referiremos a ellos, y visualizaremos susvalores, mediante sus símbolos correspondientes.

Evitando de esta manera los habituales errores de índice ennuestra programación.

Unos ejemplos de enumeraciones podrían ser lossiguientes:

La lista de meses.Los días de la semana.Los mensajes de error.¿Alguno más?

Para declarar una enumeración deberemos utilizar lapalabra clave enum, seguida de su nombre y de la lista delos símbolos correspondientes a sus valores.

enum diaSemana {lunes, martes, miércoles, jueves, viernes, sébado, domingo};

Tipos por referencia – String y StringBuilderLos tipos, además de contener los datos

correspondientes, suministran los medios para sumanipulación y almacenamiento, en caso necesario, mediantelos diferentes miembros definidos.

Por ejemplo:string cadena = "Este es el texto almacenado";

cadena = cadena.Replace("almacenado","sustituido");

Console.WriteLine(cadena");

Este es el texto sustituido

El problema con este tipo de operaciones es que los objetosde tipo string son inmutables, es decir, la sustitución anteriorno se efectuará sobre los datos iniciales de la instancia. En sulugar se creará una segunda copia de la cadena inicial, con eltexto sustituido y se cambiará el puntero del objeto al nuevocontenido, quedando los datos anteriores sin referencia, aexpensas de ser eliminados por el Garbage Collector.

Tipos por referencia – String y StringBuilderEste comportamiento es, por supuesto, transparente al

programador, por lo que uno se puede preguntar cuál puedaser la repercusión real de este comportamiento.

Se puede fácilmente imaginar una larga lista de valores decadena de caracteres a la que se deba aplicar unamodificación, concatenando un texto adicional o añadiendouna fecha, …

Cada modificación que se realice sobre cada una de lascadenas de texto creará una nueva cadena. Dada la velocidadactual de proceso de los ordenadores, la realización de laoperación anterior puede llegar a procesar grandes cantidadesde datos en muy poco tiempo. Lo cual, inicialmente, es loadecuado. El problema es que esa cantidad de variablesdescartadas y pendientes de limpieza, puede llegar a saturarla memoria del ordenador, obligando a efectuar paginacionesy operaciones que harán más lenta la operativa.

Tipos por referencia – String y StringBuilderComo alternativa a este comportamiento del tipo string,

disponemos del tipo stringBuilder, el cual ha sidooptimizado para este tipo de manipulaciones y efectúa lasmodificaciones sobre la misma instancia de datos, evitándosede esta forma la saturación antes comentada.

Adicionalmente, el tipo stringBuilder dispone de unasobrecarga de operadores que simplifica la operativa conellos:

Operador Acción

+ Une dos cadenas para crear una nueva.

== Devuelve true si las dos cadenas son iguales o false.

!= Devuelve la inversa de la operación anterior.

= Copia el contenido de una cadena en otra, actuando como un tipo por valor, aún siendo por referencia.

// Declaración del Array

Int[] tabla = {3, 1, 2};

// Ordena los valores mediante el método del tipo

Array.Sort(tabla);

// Muestra el resultado

Console.Writeline("{0}, {1}, {2}", tabla[0], tabla[1], tabla[2]);

1, 2, 3

Tipos por referencia – ArraysPermiten almacenar colecciones de valores en un único

objeto, accesibles mediante índice.Se declaran utilizando los corchetes y separando sus

elementos mediante comas.Se pueden ordenar mediante su método sort:

Tipos por referencia – StreamsPermiten el acceso de lectura y/o escritura a

dispositivos, tanto discos, como comunicaciones.La clase System.IO.Stream es la clase base para los

streams específicos para cada tipo de acceso.Disponiéndose también de streams de acceso a redes en el

espacio de nombres System.Network.Sockets y destreams encriptados en System.Security.Criptography.

Los streams básicos más comunes son:

System.IO Uso

FileStream Stream básico para acceso a disco.

MemoryStream Para acceso a memoria como si fuera disco.

StreamReader Para leer datos de un archivo de texto.

StreamWriter Para escribir datos en un archivo de texto.