更改数组大小

86

在声明后更改数组大小是否可能? 如果不行,那么有没有其他替代数组的方法?
我不想创建一个大小为1000的数组,但我在创建它时不知道数组的大小。

17个回答

98
你可以使用在MSDN中有文档记录的Array.Resize()
但是,如果你需要一个动态大小的数据结构,我同意Corey的观点,我们有List可以满足你的需求。
重要提示:Array.Resize()并不会调整数组的大小(方法名有误导性),它只是创建一个新的数组,并替换你传递给该方法的引用
以下是一个示例:
var array1 = new byte[10];
var array2 = array1;
Array.Resize<byte>(ref array1, 20);

// Now:
// array1.Length is 20
// array2.Length is 10
// Two different arrays.

1
如果Array.Resize()只在程序开始时调用一次(而不是在程序中多次调用),那么使用它是否比List更合适? - Dan W
5
List<T>在幕后使用数组,因此在C#中几乎没有使用数组的理由。可以使用此构造函数将列表初始化为适当的大小:http://msdn.microsoft.com/en-us/library/dw8e0z9z.aspx 。但是,如果你非常想用数组,最好尽可能少地调整它们的大小。 - Chris Shain
8
注意,Array.Resize不会保留您的引用,而是创建一个所需大小的新数组。 - Loul G.
2
List<Int> 在底层使用了 Array.Resize。它使用了一种通常(虽然不是普遍)最优的算法,在每次增长时将数组大小加倍。除非您正在开发高性能实时系统(例如高速交易或机械控制系统),否则应该使用 List<Int>,因为它足够好并且更易于维护。 - Chris Shain
@ChrisShain,如果它不删除旧引用,我们该如何删除旧引用? - AminM
显示剩余5条评论

68
不,尝试使用强类型的List

例如:

不要使用

int[] myArray = new int[2];
myArray[0] = 1;
myArray[1] = 2;

您可以这样做:

List<int> myList = new List<int>();
myList.Add(1);
myList.Add(2);

列表使用数组来存储数据,因此您可以获得数组的速度优势,并且通过能够添加和删除项目而不必担心手动更改其大小,从而方便了LinkedList的使用。

然而,这并不意味着一个数组的大小(在本例中是一个List)不会改变 - 因此强调手动这个词。

一旦你的数组达到预定义的大小,JIT将在堆上分配一个新的两倍大小的数组,并将现有的数组复制过去。


2
是的,通过这种方式:string[] arr1 = new string[]{}; Array.Resize(ref arr1, 7); - Mohamed Abulnasr

14

是的,可以调整数组大小。例如:

int[] arr = new int[5];
// increase size to 10
Array.Resize(ref arr, 10);
// decrease size to 3
Array.Resize(ref arr, 3);
如果您使用CreateInstance()方法创建一个数组,那么Resize()方法将无法正常工作。例如:

如果您使用CreateInstance()方法创建一个数组,那么Resize()方法将无法正常工作。

// create an integer array with size of 5
var arr = Array.CreateInstance(typeof(int), 5);
// this not work
Array.Resize(ref arr, 10);

数组大小是不可变的,即使我们可以调整其大小。如果您想要一个动态数组,我认为我们可以使用泛型列表(List)。

var list = new List<int>();
// add any item to the list
list.Add(5);
list.Add(8);
list.Add(12);
// we can remove it easily as well
list.Remove(5);
foreach(var item in list)
{
  Console.WriteLine(item);
}

13
您可以在 .NET 3.5 及更高版本中使用 Array.Resize() 方法。该方法会分配一个指定大小的新数组,将旧数组中的元素复制到新数组中,然后用新数组替换旧数组。(由于此方法可能在底层使用了Array.Copy,因此需要为两个数组都保留可用内存空间。)

7
在C#中,数组不能动态调整大小。
  • One approach is to use System.Collections.ArrayList instead of a native array.

  • Another (faster) solution is to re-allocate the array with a different size and to copy the contents of the old array to the new array.

    The generic function resizeArray (below) can be used to do that.

    public static System.Array ResizeArray (System.Array oldArray, int newSize)  
        {
          int oldSize = oldArray.Length;
          System.Type elementType = oldArray.GetType().GetElementType();
          System.Array newArray = System.Array.CreateInstance(elementType,newSize);
    
          int preserveLength = System.Math.Min(oldSize,newSize);
    
          if (preserveLength > 0)
          System.Array.Copy (oldArray,newArray,preserveLength);
    
         return newArray; 
      }  
    
     public static void Main ()  
           {
            int[] a = {1,2,3};
            a = (int[])ResizeArray(a,5);
            a[3] = 4;
            a[4] = 5;
    
            for (int i=0; i<a.Length; i++)
                  System.Console.WriteLine (a[i]); 
            }
    

6

Used this approach for array of bytes:

Initially:

byte[] bytes = new byte[0];

每当需要时(需要提供原始长度以扩展):

Array.Resize<byte>(ref bytes, bytes.Length + requiredSize);

重置:

Array.Resize<byte>(ref bytes, 0);

Typed List Method

最初:

List<byte> bytes = new List<byte>();

在需要的时候:

bytes.AddRange(new byte[length]);

发布/清除:

bytes.Clear()

5
使用 List<T> 代替。例如,用 int 类型的列表代替数组。
private int[] _myIntegers = new int[1000];

使用
private List<int> _myIntegers = new List<int>();

稍后
_myIntegers.Add(1);


4
在C#中,Array.Resize是将任何数组调整为新大小的最简单方法,例如:
Array.Resize<LinkButton>(ref area, size);

在这里,我想调整LinkButton数组的大小:

<LinkButton> = 指定数组类型
ref area = ref是一个关键字,'area'是数组名称
size = 新的数组大小


3
    private void HandleResizeArray()
    {
        int[] aa = new int[2];
        aa[0] = 0;
        aa[1] = 1;

        aa = MyResizeArray(aa);
        aa = MyResizeArray(aa);
    }

    private int[] MyResizeArray(int[] aa)
    {
        Array.Resize(ref aa, aa.GetUpperBound(0) + 2);
        aa[aa.GetUpperBound(0)] = aa.GetUpperBound(0);
        return aa;
    }

通过执行UpperBound,您要做什么? - whihathac

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接