【问题标题】:change array size更改数组大小
【发布时间】:2011-06-17 23:14:58
【问题描述】:

声明后可以更改数组大小吗? 如果没有,是否有任何替代数组的方法?
我不想创建一个大小为 1000 的数组,但是我在创建它时不知道数组的大小。

【问题讨论】:

    标签: c# arrays size


    【解决方案1】:

    您可以使用Array.Resize(),记录在MSDN

    但是,是的,我同意 Corey 的观点,如果您需要动态大小的数据结构,我们有 Lists 来解决这个问题。

    重要提示:Array.Resize() 不会调整数组的大小(方法名称具有误导性),它会创建一个新数组并仅替换您传递给方法的 reference

    一个例子:

    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.
    

    【讨论】:

    • 如果 Array.Resize() 在开始时只有一次(而不是在程序中多次),那是否比 List 更合适?
    • List&lt;T&gt; 在后台使用数组,因此在 C# 中使用数组的理由很少。可以使用以下构造函数将列表初始化为合适的大小:msdn.microsoft.com/en-us/library/dw8e0z9z.aspx。但是,是的,如果您的心是阵列,最好尽可能不频繁地调整它们的大小。
    • 我认为 List 使用了链表或背后的一些数据结构。所以它毕竟使用数组。
    • 小心,Array.Resize 不会保留您的参考。相反,它会创建一个所需大小的新数组。
    • List&lt;Int&gt; 在幕后使用 Array.Resize。它在幕后使用了一般(尽管不是普遍)的最佳算法,其中每次增长数组时,它都会将数组的大小加倍。除非您正在开发高性能实时系统(例如高速交易或机械控制系统),否则您应该使用 List&lt;Int&gt;,因为它“足够好”并且更易于维护。
    【解决方案2】:

    不,请尝试使用强类型 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 就会在堆上分配一个两倍大小的新数组,并复制您现有的数组。

    【讨论】:

    • 是这样的:string[] arr1 = new string[]{}; Array.Resize(ref arr1, 7);
    【解决方案3】:

    您可以在 .net 3.5 及更高版本中使用 Array.Resize()。此方法分配一个指定大小的新数组,将元素从旧数组复制到新数组,然后用新数组替换旧数组。 (因此您需要为两个数组提供可用的内存,因为这可能在幕后使用Array.Copy

    【讨论】:

      【解决方案4】:

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

      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() 方法不起作用。例如:

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

      【讨论】:

        【解决方案5】:

        在 C# 中,不能动态调整数组的大小。

        • 一种方法是使用 System.Collections.ArrayList 改为 native array

        • 另一个(更快)的解决方案是 重新分配数组 不同的大小和复制 旧数组的内容到新的 数组。

          通用函数 resizeArray(如下)可用于执行此操作。

          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】:

          将此方法用于字节数组:

          最初:

          byte[] bytes = new byte[0];
          

          根据需要(需要提供原长度以进行延长):

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

          重置:

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

          类型列表法

          最初:

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

          需要时:

          bytes.AddRange(new byte[length]);
          

          释放/清除:

          bytes.Clear()
          

          【讨论】:

            【解决方案7】:

            【讨论】:

              【解决方案8】:

              请改用List&lt;T&gt;。例如,而不是整数数组

              private int[] _myIntegers = new int[1000];
              

              使用

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

              稍后

              _myIntegers.Add(1);
              

              【讨论】:

                【解决方案9】:

                在 C# 中,Array.Resize 是将任何数组调整为新大小的最简单方法,例如:

                Array.Resize<LinkButton>(ref area, size);
                

                在这里,我想调整 LinkBut​​ton 数组的数组大小:

                &lt;LinkButton&gt; = 指定数组类型
                ref area = ref 是关键字,'area' 是数组名称
                size = 新大小数组

                【讨论】:

                  【解决方案10】:
                      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做什么?
                  【解决方案11】:

                  当您想要添加/删除数据时,请使用列表(其中 T 是任何类型或对象),因为调整数组大小的成本很高。您可以阅读有关Arrays considered somewhat harmful 的更多信息,而可以将列表添加到新记录可以附加到末尾。它会根据需要调整其大小。

                  可以通过以下方式初始化列表

                  使用集合初始化器。

                  List<string> list1 = new List<string>()
                  {
                      "carrot",
                      "fox",
                      "explorer"
                  };
                  

                  将 var 关键字与集合初始化器一起使用。

                  var list2 = new List<string>()
                  {
                      "carrot",
                      "fox",
                      "explorer"
                  };
                  

                  使用新数组作为参数。

                  string[] array = { "carrot", "fox", "explorer" };
                  List<string> list3 = new List<string>(array);
                  

                  在构造函数中使用容量并赋值。

                  List<string> list4 = new List<string>(3);
                  list4.Add(null); // Add empty references. (Not Recommended)
                  list4.Add(null);
                  list4.Add(null);
                  list4[0] = "carrot"; // Assign those references.
                  list4[1] = "fox";
                  list4[2] = "explorer";
                  

                  对每个元素使用 Add 方法。

                  List<string> list5 = new List<string>();
                  list5.Add("carrot");
                  list5.Add("fox");
                  list5.Add("explorer");
                  

                  因此,对于一个对象列表,您可以分配和分配与列表初始化内联的对象的属性。对象初始化器和集合初始化器共享相似的语法。

                  class Test
                  {
                      public int A { get; set; }
                      public string B { get; set; }
                  }
                  

                  用集合初始化器初始化列表。

                  List<Test> list1 = new List<Test>()
                  {
                      new Test(){ A = 1, B = "Jessica"},
                      new Test(){ A = 2, B = "Mandy"}
                  };
                  

                  用新对象初始化列表。

                  List<Test> list2 = new List<Test>();
                  list2.Add(new Test() { A = 3, B = "Sarah" });
                  list2.Add(new Test() { A = 4, B = "Melanie" });
                  

                  【讨论】:

                    【解决方案12】:

                    这对我来说很有效,可以从类数组创建动态数组。

                    var s = 0;
                    var songWriters = new SongWriterDetails[1];
                    foreach (var contributor in Contributors)
                    {
                        Array.Resize(ref songWriters, s++);
                        songWriters[s] = new SongWriterDetails();
                        songWriters[s].DisplayName = contributor.Name;
                        songWriters[s].PartyId = contributor.Id;
                        s++;
                    }
                    

                    【讨论】:

                      【解决方案13】:

                      如果您确实需要将其重新转换为数组,我发现将array 转换为list 最简单,展开列表然后将其转换回array

                              string[] myArray = new string[1] {"Element One"};
                              // Convert it to a list
                              List<string> resizeList = myArray.ToList();
                              // Add some elements
                              resizeList.Add("Element Two");
                              // Back to an array
                              myArray = resizeList.ToArray();
                              // myArray has grown to two elements.
                      

                      【讨论】:

                        【解决方案14】:

                        如果您不能使用Array.Reset(变量不是本地变量),那么Concat & ToArray 会有所帮助:

                        anObject.anArray.Concat(new string[] { newArrayItem }).ToArray();
                        

                        【讨论】:

                          【解决方案15】:

                          使用通用列表 (System.Collections.Generic.List)。

                          【讨论】:

                            猜你喜欢
                            • 2017-07-03
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            • 2015-01-24
                            • 1970-01-01
                            • 1970-01-01
                            • 1970-01-01
                            相关资源
                            最近更新 更多