2015-09-29 4 views
1

У меня есть массив с Length = 3 и со значениями, например {1,2,3}. Мне нужно динамически изменять его размер.Как динамически изменять размер массива?

Я знаю, что могу использовать List или Array.Resize(). Но мне нужно знать, как реализовать свой собственный метод изменения размера?

+1

Проблема в том, что любые ссылки на старый массив не будут меняться для ссылки на новый массив. – crashmstr

+0

https://msdn.microsoft.com/en-us/library/bb348051(v=vs.110).aspx Вы можете посмотреть исходный источник для этого и посмотреть, как они это сделали, но это должно быть довольно очевидно. –

+1

в основном, создайте новый массив – VisualBean

ответ

3

Вы можете попробовать следующий код. Создайте новый массив с новым размером и скопируйте старые данные массива во вновь созданный массив.

public static Array ResizeArray (Array oldArray, int newSize) 
    int oldSize = oldArray.Length; 
    Type elementType = oldArray.GetType().GetElementType(); 
    Array newArray = Array.CreateInstance(elementType,newSize); 
    int preserveLength = System.Math.Min(oldSize,newSize); 
    if (preserveLength > 0){ 
     Array.Copy (oldArray,newArray,preserveLength); 
    } 
    retuen newArray; 
} 
+2

OP не хочет использовать метод 'Array.Resize'. –

+1

@FelipeOriani Я исправил его. –

+1

Good one Saveendra! –

-1

Сделайте массив нового желаемого размера, скопируйте все предметы. Сделайте переменную, на которую ссылается ссылка старого массива на новый.

код из MSDN:

public static void Resize<T>(ref T[] array, int newSize) { 
    if (newSize < 0) { 
     throw new ArgumentOutOfRangeException("newSize", Environment.GetResourceString("ArgumentOutOfRange_NeedNonNegNum")); 
     Contract.Ensures(Contract.ValueAtReturn(out array) != null); 
     Contract.Ensures(Contract.ValueAtReturn(out array).Length == newSize); 
     Contract.EndContractBlock(); 

     T[] larray = array;     
     if (larray == null) { 
      array = new T[newSize]; 
      return; 
     } 

     if (larray.Length != newSize) { 
      T[] newArray = new T[newSize]; 
      Array.Copy(larray, 0, newArray, 0, larray.Length > newSize? newSize : larray.Length); 
      array = newArray; 
     } 
    } 
} 
0

Если вы хотите изменить размер массива использовать сборки в методе массива .Resize(). Это будет проще и быстрее.

Если вам нужна динамическая структура данных, используйте для этого список List. Вы всегда можете сделать array.ToList() -> заполнить список и сделать .ToArray() позже.

1

Если это только для практики, сделайте это. но я предлагаю вам использовать .Net Array.Resize(), если вы хотите использовать его в своем коде. обычно библиотеки .NET лучше всего реализуются и оптимизируются.

В любом случае ... Вы можете сделать это с общим методом

private static void Resize<T>(ref T[] array,int size) 
{ 
    T[] token = array.Take(size).ToArray(); // attempt to take first n elements 
    T[] temp = new T[size]; // create new reference 
    token.CopyTo(temp, 0); // copy array contents to new array 
    array = temp; // change reference 
} 

Обратите внимание, что вы не можете сделать это без параметра ref. (Другой способ - вернуть массив, конечно)

Вы можете подумать, что массивы передаются по ссылке. это правда. Но ссылки на него передаются по значению. поэтому всякий раз, когда вы пытаетесь изменить ссылку, он больше не ссылается на исходный массив. вы можете изменить содержимое. Чтобы сделать это возможным, вы должны использовать ref, чтобы напрямую передать ссылку в метод.

О коде:

{1,2,3}, если размер его 2, очевидно, это будет удалить последний параметр. так что у вас будет {1,2}

если вы измените его размер до 4, то он даст массив с новыми значениями по умолчанию. либо null для ссылочных типов, либо 0 для типов значений (false для булевого типа). здесь у вас будет {1,2,3,0}

int[] array = new[] {1, 2, 3}; 
Resize(ref array,4); 
Console.WriteLine(array.Length); // outputs 4 
Смежные вопросы