web-dev-qa-db-fra.com

Redim Preserve en C #?

J'ai été choqué de découvrir aujourd'hui que C # ne prend pas en charge les tableaux de taille dynamique. Comment un développeur VB.NET avait-il l'habitude d'utiliser ReDim Preserve pour gérer cela en C #?

Au début de la fonction, je ne suis pas sûr de la limite supérieure du tableau. Cela dépend des lignes renvoyées par la base de données.

37
JL.

Utilisez plutôt ArrayLists ou Generics

11
Michael L

VB.NET n'a pas non plus l'idée de tableaux de taille dynamique - le CLR ne le prend pas en charge.

L'équivalent de "Redim Preserve" est Array.Resize<T> - mais vous devez être conscient que s'il existe d'autres références au tableau d'origine, elles ne seront pas modifiées du tout. Par exemple:

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
    }
}

Preuve qu'il s'agit de l'équivalent 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

Les deux programmes sont équivalents.

Si vous voulez vraiment une collection de taille dynamique, vous devez utiliser List<T> (ou quelque chose de similaire). Il y a plusieurs problèmes avec l'utilisation directe des tableaux - voir Article de blog d'Eric Lippert pour plus de détails. Cela ne veut pas dire que vous devriez toujours les éviter, par tous les moyens - mais vous devez savoir à quoi vous avez affaire.

74
Jon Skeet

Utilisez une liste <T>. Il dimensionnera dynamiquement selon les besoins.

10
driis

Vous ne devriez vraiment pas utiliser ReDim, cela peut coûter très cher. Je préfère List (Of T), mais il existe de nombreuses options dans ce domaine.

Cela dit, vous aviez une question et voici votre réponse.

x = (int[]) Utils.CopyArray((Array) x, new int[10]);
4
Jonathan Allen

Je n'ai pas pu m'empêcher de remarquer que aucun des réponses ci-dessus approchent le concept de tableaux multidimensionnels. Cela étant dit, voici un exemple. Le tableau en question est prédéfini comme 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;
2
Hameer Abbasi

Juste pour le plaisir, voici une façon d'utiliser les génériques afin de redéfinir/étendre un tableau unidimensionnel (ajoutez une autre "ligne"):

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;
}

Et un pour ajouter n lignes (bien que cela n'empêche pas l'utilisateur de sous-dimensionner le tableau, ce qui générera une erreur dans la boucle 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;
}

Je suis sûr que vous avez l'idée.

Pour un tableau multidimensionnel (deux dimensions), voici une possibilité:

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;
}

Dans votre programme, utilisez ceci avec ou même sans le type spécifié, le compilateur le reconnaîtra:

int[] myArr = new int[10];
myArr = Redim<int>(myArr, true);

ou

int[] myArr = new int[10];
myArr = Redim(myArr, true);

Je ne sais pas si tout cela est vraiment pertinent. = D N'hésitez pas à me corriger ou à améliorer mon code. ;)

2
Tete1805

Même s'il y a longtemps, cela pourrait aider quelqu'un à la recherche d'une solution simple - j'ai trouvé quelque chose de génial dans un autre forum:

//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;
        }

Source: https://social.msdn.Microsoft.com/Forums/en-US/6759816b-d525-4752-a3c8-9eb5f4a5b194/redim-in-c?forum=csharplanguage

1
AllDayPiano