Una ventaja, pero también a la vez un inconveniente, de las estructuras dinámicas que hemos visto, es que permiten guardar datos de cualquier tipo, incluso datos de distinto tipo en una misma estructura: un ArrayList que contenga primero un string, luego un número entero, luego uno de coma flotante, después un struct… Esto obliga a que hagamos una "conversión de tipos" con cada dato que obtenemos (excepto con los "strings").
En ocasiones puede ser interesante algo un poco más rígido, que, con las ventajas de un ArrayList (crecimiento dinámico, múltiples métodos disponibles), esté adaptado a un tipo concreto de datos, y no necesite una conversión de tipos cada vez que extraigamos un dato.
Por ello, en la versión 2 de la "plataforma .Net" se introdujeron los "generics", que definen estructuras de datos genéricas, que nosotros podemos particularizar en cada uso. Por ejemplo, una lista de strings se definiría con:
List miLista = new List();
Y necesitaríamos incluir un nuevo "using" al principio del programa:
using System.Collections.Generic;
Con sólo estos dos cambios, el ejemplo de uso de ArrayList que vimos en el apartado 11.4.1 funcionaría perfectamente:
// Ejemplo_11_08a.cs
// Ejemplo de List
// Introducción a C#, por Nacho Cabanes
using System;
using System.Collections.Generic;
public class Ejemplo_11_08a
{
public static void Main()
{
List miLista = new List();
// Añadimos en orden
miLista.Add("Hola,");
miLista.Add("soy");
miLista.Add("yo");
// Mostramos lo que contiene
Console.WriteLine( "Contenido actual:");
foreach (string frase in miLista)
Console.WriteLine( frase );
// Accedemos a una posición
Console.WriteLine( "La segunda palabra es: {0}",
miLista[1] );
// Insertamos en la segunda posicion
miLista.Insert(1, "Como estas?");
// Mostramos de otra forma lo que contiene
Console.WriteLine( "Contenido tras insertar:");
for (int i=0; i= 0)
Console.WriteLine( "Está en la posición {0}", posicion );
else
Console.WriteLine( "No está. El dato inmediatamente mayor "+
"es el {0}: {1}",
~posicion, miLista[~posicion] );
}
}
De esta misma forma, podríamos crear una lista de structs, o de objetos, o de cualquier otro dato.
No sólo tenemos listas. Por ejemplo, también existe un tipo "Dictionary", que equivale a una tabla Hash, pero en la que las claves y los valores no tienen por qué ser strings, sino el tipo de datos que nosotros decidamos. Por ejemplo, podemos usar una cadena como clave, pero un número entero como valor obtenido:
Dictionary dict = new Dictionary();
Así, con un diccionario que tenga tanto claves string como valores string, podríamos crear una versión alternativa del ejemplo 11_05b. Los únicos cambios serían una declaración parecida a la anterior, el "using" correcto, y cambiar Contains por ContainsKey:
// Ejemplo_11_08b.cs
// Ejemplo de Dictionary
// Introducción a C#, por Nacho Cabanes
using System;
using System.Collections.Generic;
public class Ejemplo_11_08b
{
public static void Main()
{
// Creamos e insertamos datos
Dictionary miDiccio =
new Dictionary();
miDiccio.Add("byte", "8 bits");
miDiccio.Add("pc", "personal computer");
miDiccio.Add("kilobyte", "1024 bytes");
// Mostramos algún dato
Console.WriteLine( "Cantidad de palabras en el diccionario: {0}",
miDiccio.Count );
if (miDiccio.ContainsKey("pc"))
Console.WriteLine( "El significado de PC es: {0}",
miDiccio["pc"]);
else
Console.WriteLine( "No existe la palabra PC");
}
}
Ejercicios propuestos:
Ejercicio propuesto 11.8.1: Crea una nueva versión de la "bases de datos de ficheros" (ejemplo 04_06a), pero usando List en vez de un array convencional.
Ejercicio propuesto 11.8.2: Crea un programa que lea todo el contenido de un fichero, lo guarde en una lista de strings y luego lo muestre en orden inverso (de la última línea a la primera).