redim - c# array resize example
Redim Preserve en C#? (7)
Me sorprendió descubrir hoy que C # no es compatible con matrices de tamaño dinámico. Entonces, ¿cómo un desarrollador de VB.NET solía usar ReDim Preserve para lidiar con esto en C #?
Al comienzo de la función, no estoy seguro del límite superior de la matriz. Esto depende de las filas devueltas desde la base de datos.
A pesar de que fue hace mucho tiempo que podría ayudar a alguien que busca una solución simple, encontré algo grandioso en otro foro:
//from Applied Microsoft.NET framework Programming - Jeffrey Richter
public static Array RedimPreserve(Array origArray, Int32 desiredSize)
{
System.Type t = origArray.GetType().GetElementType();
Array newArray = Array.CreateInstance(t, desiredSize);
Array.Copy(origArray, 0, newArray, 0, Math.Min(origArray.Length, desiredSize));
return newArray;
}
No pude evitar observar que ninguna de las respuestas anteriores aborda el concepto de matrices multidimensionales. Dicho esto, aquí hay un ejemplo. La matriz en cuestión está predefinida como x
.
int[,] temp = new int[newRows, newCols];
int minRows = Math.Min(newRows, x.GetUpperBound(0) + 1);
int minCols = Math.Min(newCols, x.GetUpperBound(1) + 1);
for (int i = 0; i < minRows ; ++i)
for (int j = 0; j < minCols; ++j)
temp[i, j] = x[i, j];
x = temp;
Realmente no debería usar ReDim, puede ser costoso. Prefiero la Lista (De T), pero hay muchas opciones en esta área.
Dicho esto, tienes una pregunta y aquí está tu respuesta.
x = (int[]) Utils.CopyArray((Array) x, new int[10]);
Solo por diversión, aquí hay una forma de usar genéricos para redirigir / extender una matriz unidimensional (agregue una "fila" más):
static T[] Redim<T>(T[] arr, bool preserved)
{
int arrLength = arr.Length;
T[] arrRedimed = new T[arrLength + 1];
if (preserved)
{
for (int i = 0; i < arrLength; i++)
{
arrRedimed[i] = arr[i];
}
}
return arrRedimed;
}
Y uno para agregar n filas (aunque esto no impide que el usuario subestime la matriz, lo que arrojará un error en el bucle for):
static T[] Redim<T>(T[] arr, bool preserved, int nbRows)
{
T[] arrRedimed = new T[nbRows];
if (preserved)
{
for (int i = 0; i < arr.Length; i++)
{
arrRedimed[i] = arr[i];
}
}
return arrRedimed;
}
Estoy seguro de que entiendes la idea.
Para una matriz multidimensional (dos dimensiones), aquí hay una posibilidad:
static T[,] Redim<T>(T[,] arr, bool preserved)
{
int Ubound0 = arr.GetUpperBound(0);
int Ubound1 = arr.GetUpperBound(1);
T[,] arrRedimed = new T[Ubound0 + 1, Ubound1];
if (preserved)
{
for (int j = 0; j < Ubound1; j++)
{
for (int i = 0; i < Ubound0; i++)
{
arrRedimed[i, j] = arr[i, j];
}
}
}
return arrRedimed;
}
En su programa, use esto con o incluso sin el tipo especificado, el compilador lo reconocerá:
int[] myArr = new int[10];
myArr = Redim<int>(myArr, true);
o
int[] myArr = new int[10];
myArr = Redim(myArr, true);
Sin embargo, no estoy seguro de si todo esto es realmente relevante. = D Por favor, siéntete libre de corregirme o mejorar mi código. ;)
Use ArrayLists o Generics en su lugar
Use una lista <T>. Dimensará dinámicamente según sea necesario.
VB.NET tampoco tiene la idea de matrices de tamaño dinámico: el CLR no lo admite.
El equivalente de "Redim Preserve" es Array.Resize<T>
, pero debe tener en cuenta que si hay otras referencias a la matriz original, no se modificarán en absoluto. Por ejemplo:
using System;
class Foo
{
static void Main()
{
string[] x = new string[10];
string[] y = x;
Array.Resize(ref x, 20);
Console.WriteLine(x.Length); // Prints out 20
Console.WriteLine(y.Length); // Still prints out 10
}
}
Prueba de que esto es el equivalente de Redim Preserve:
Imports System
Class Foo
Shared Sub Main()
Dim x(9) as String
Dim y as String() = x
Redim Preserve x(19)
Console.WriteLine(x.Length)
Console.WriteLine(y.Length)
End Sub
End Class
Los dos programas son equivalentes.
Si realmente quieres una colección de tamaño dinámico, debes usar List<T>
(o algo similar). Existen varios problemas con el uso de matrices directamente: consulte la publicación de blog de Eric Lippert para obtener más información. Eso no quiere decir que siempre debes evitarlos, de ninguna manera, pero debes saber con qué estás tratando.