Redim сохранить в С#?

Я был потрясен, узнав сегодня, что С# не поддерживает массивы динамического размера. Как тогда разработчик VB.NET использовал ReDim Preserve справиться с этим в С#?

В начале функции я не уверен в верхней границе массива. Это зависит от строк, возвращаемых из базы данных.

Ответ 1

Используйте ArrayLists или Generics вместо

Ответ 2

VB.NET не имеет представления о массивах с динамическим размером: CLR не поддерживает его.

Эквивалент "Redim Preserve" Array.Resize<T> - но вы должны знать, что если есть другие ссылки на исходный массив, они не будут изменены вообще. Например:

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

Доказательство того, что это эквивалент 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

Две программы эквивалентны.

Если вам действительно нужна коллекция с динамическим размером, вы должны использовать List<T> (или что-то подобное). Существуют различные проблемы с использованием массивов напрямую - см. сообщение в блоге Eric Lippert. Это не значит, что вы всегда должны избегать их, любыми средствами, но вам нужно знать, с чем вы имеете дело.

Ответ 3

Используйте список <T> . Он будет динамически изменяться по мере необходимости.

Ответ 4

Вы действительно не должны использовать ReDim, это может быть дорого. Я предпочитаю List (Of T), но в этой области есть много вариантов.

Тем не менее, у вас возник вопрос, и вот ваш ответ.

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

Ответ 5

Просто для удовольствия, здесь один из способов использования дженериков для того, чтобы переделать/расширить одномерный массив (добавьте еще одну "строку" ):

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

И один, чтобы добавить n строк (хотя это не помешает пользователю переопределить массив, что вызовет ошибку в цикле 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;
}

Я уверен, что вы поняли.

Для многомерного массива (два измерения) здесь есть одна возможность:

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

В вашей программе используйте это с или даже без указанного типа, компилятор узнает его:

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

или

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

Не уверен, что все это действительно актуально. = D Не стесняйтесь исправлять меня или улучшать код.;)

Ответ 6

Я не мог не заметить, что ни один из приведенных выше ответов не подходит к концепции многомерных массивов. Сказанное здесь - вот пример. Массив, о котором идет речь, предопределен как 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;

Ответ 7

Несмотря на то, что давно это могло помочь кому-то найти простое решение - я нашел что-то отличное в другом форуме:

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

Источник: https://social.msdn.microsoft.com/Forums/en-US/6759816b-d525-4752-a3c8-9eb5f4a5b194/redim-in-c?forum=csharplanguage