2008-11-29 3 views
32

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

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

+15

Я думаю, другая сторона будет «Я потрясен, узнав, что VB поддерживает массивы с динамическим размером». – user7116 2008-11-30 19:00:56

+0

yeah sixlettervariables, кажется, массивы с динамическим размером были слишком просты в использовании, но с серьезной производительностью. – 2008-12-09 06:51:21

ответ

11

Используйте ArrayLists или Дженерики вместо

+9

Точнее, используйте Список . В .NET существует множество универсальных классов или функций, которые не изменяют размер массивов. ;) – jalf 2008-11-29 19:52:49

10

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

+4

+1 никогда не используйте ArrayList. – user7116 2008-11-29 20:51:38

+0

@ user7116 *** никогда ***? почему и причины? – Kiquenet 2017-11-08 21:48:52

4

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

У вас возникли вопросы, и вот ваш ответ.

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

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

Эквивалент «Redim заповедника» является 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's blog post для деталей. Это не значит, что вы всегда должны избегать их, любыми средствами - но вам нужно знать, с чем вы имеете дело.

2

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

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

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

и один, чтобы добавить п строк (хотя это не мешает пользователю занижения массива, который будет бросать ошибку в цикл):

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 Пожалуйста, не стесняйтесь исправить меня или улучшить код. ;)

1

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

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

Смежные вопросы