Siguiendo con el post anterior de las matrices, vamos a ver ahora como emular de forma genérica la instrucción Redim Preserve de Visual Basic desde C#.
private static Array RedimPreserve(Array matriz, int nuevoTamanho)
{
Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho);
int longACopiar = nuevoTamanho;
if (nuevoTamanho > matriz.Length) longACopiar = matriz.Length;
Array.Copy(matriz, 0, m, 0, longACopiar);
return m;
}
Esta versión devuelve una matriz con el tamaño indicado y preservando los elementos contenidos en la matriz original. Se usa el método Copy de la clase Array para copiar de manera eficiente los elementos y evitar hacer un bucle.
Al igual que en el post anterior también podemos considerar la versión que transforma directamente la matriz que se le pase por referencia:
private static void RedimPreserve(ref Array matriz, int nuevoTamanho)
{
Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), nuevoTamanho);
int longACopiar = nuevoTamanho;
if (nuevoTamanho > matriz.Length) longACopiar = matriz.Length;
Array.Copy(matriz, 0, m, 0, longACopiar);
matriz = m;
}
Siguiendo las mismas pautas de programación podemos escribir otras funciones relacionadas con matrices escritas de forma genérica, por ejemplo las siguientes:
private static Array AddElemento(Array matriz, object Elto)
{
Array m = Array.CreateInstance(Elto.GetType(), matriz.Length+1);
Array.Copy(matriz, 0, m, 0, matriz.Length);
m.SetValue(Elto, m.GetUpperBound(0));
return m;
}
private static Array BorraElementos(Array matriz, int[] eltos)
{
//Se ordenan los índices de los elementos a eliminar
Array.Sort(eltos);
//se quita el primero...
Array aux = BorraElemento(matriz, eltos[0]);
int Anterior = eltos[0]; //para evitar repeticiones de índices a eliminar
//Ahora se recorren el resto de los elementos a eliminar...
int Offset = 1;
for(int i=1;i<eltos.Length;i++)
{
//Si el elemento no es repetido...
if (eltos[i] > Anterior)
{
//...se borra el elemento correspondiente
aux = BorraElemento(aux, eltos[i]-Offset);
//se anota como anterior...
Anterior = eltos[i];
//...y se suma uno a la cantidad a restar (hay un elemento menos)
Offset++;
}
}
return aux;
}
private static Array BorraElemento(Array matriz, int indice)
{
//Si el índice está fuera de los límites se lanza una excepción
if (indice > matriz.GetUpperBound(0)) throw(new System.IndexOutOfRangeException());
//Se crea una nueva matriz del mismo tipo (el mismo que su primer elemento) y con el tamaño adecuado...
Array m = Array.CreateInstance(matriz.GetValue(0).GetType(), matriz.Length-1);
//...se copian los elementos de la original menos el eliminado...
Array.Copy(matriz,0, m, 0, indice);
Array.Copy(matriz,indice+1,m,indice,m.Length-indice);
//... y se devuelve.
return m;
}
Espero que este par de textos sirvan para ilustrar el trabajo con matrices genéricas en la plataforma .NET.