【问题标题】:is there a way to treat a c# static array like an ArrayList?有没有办法像 ArrayList 一样对待 c# 静态数组?
【发布时间】:2009-03-12 15:59:34
【问题描述】:

我有使用数组的代码,不幸的是,我无法更改它们的类型。如果可以的话,我会使用 ArrayLists 或类似的东西来做我需要做的事情,但我不能。基本上,我正在寻找从静态数组中添加和删除对象的最佳方法。为了即时向数组中添加一个项目,我必须创建一个比旧数组大一个元素的新数组,将旧数组中的项目复制到新数组中,然后添加新项目。像这样...

public partial class dataStruct 
{
    private myObject[] myStaticArray;
};

private void AddItemToMyArray()
{
    int oldLength = dataStruct.myStaticArray.Length;
    myObject[] newMyObjectArray = new myObject[oldLength + 1];
    for (int i = 0; i < oldLength; i++)
       newMyObjectArray [i] = dataStruct.myStaticArray[i];

    dataStruct.myStaticArray[oldLength] = new myObject();
    dataStruct.myStaticArray = newMyObjectArray;
}

为了删除一个项目,我做同样的事情,只是我创建了一个小一个项目的新数组。这感觉真的效率低下。任何人都可以提出更好的方法,如果有的话?还是有其他想法?

提前感谢您的帮助!

【问题讨论】:

  • 从 .NET 2.0 开始,您可以使用 List 代替数组。

标签: c# arrays arraylist


【解决方案1】:

否 - 数组始终是固定大小的。您不能从中添加/删除条目。

这正是ArrayListList&lt;T&gt; 有效解决的限制。它们在内部维护一个数组,但通常大于列表的逻辑大小。当您将项目添加到List&lt;T&gt; 时,如果可以,它将填充现有数组,或者如果没有足够的空间,它将创建一个新的更大的数组并将内容复制到其中。不过,此更改对调用者是透明的 - 您仍然可以使用原始引用,因为它是对列表的引用,而不是对底层数组的引用。

让您的代码更简单(但可能不会更高效)的一件事是使用Array.Resize。它不会调整 现有 数组的大小,而是返回一个新数组,其中包含旧内容的浅表副本,大小为您请求的大小。复制可能比手动循环快一点,但效率低下的主要原因仍然存在。

【讨论】:

    【解决方案2】:

    为什么要在这里使用数组?切换到List&lt;T&gt;,或者(如果您需要从中间有效移除/插入)LinkedList&lt;T&gt;

    我不确定你的意思是不是我所说的“静态”——你能澄清一下吗?

    有关信息,您可以使用Array.Resize(ref myArray, newSize),但这不是频繁更改的正确答案。

    【讨论】:

    • 为了扩展这一点,因为他现在抱怨他不能,所以 List 类有一个 .ToArray() 方法,您可以在需要使用需要数组的 API 时调用.
    • 既然他现在“解释”了他不能。 =P
    【解决方案3】:

    很遗憾,我无法更改它们的类型

    为什么不呢?唯一合理的答案是您有一个 API,您必须将其与返回它们或要求它们作为参数的函数一起使用。在这种情况下,使用List&lt;T&gt; 并根据需要调用它的.ToArray().AddRange() 方法。

    【讨论】:

      【解决方案4】:

      听上去你不能改变数据结构,所以必须处理数组。

      你真正能得到帮助的唯一一件事就是你可以避免循环并做一个 Array.copy

      int oldLength = dataStruct.myStaticArray.Length;
      myObject[] newMyObjectArray = new myObject[oldLength + 1];
      Array.copy(dataStruct.myStaticArray, newMyObjectArray, oldLength);
      
      dataStruct.myStaticArray[oldLength] = new myObject();
      dataStruct.myStaticArray = newMyObjectArray;
      

      编辑实际上这可能有效:

      int oldLength = dataStruct.myStaticArray.Length;
      Array.Resize(dataStruct.myStaticArray, oldLength+1);
      

      【讨论】:

      • 仅供参考 - Array.Copy 实际上通常比循环慢。在这种情况下,它会在每个副本内部进行装箱/拆箱,因为您正在复制整数。这是 .net2 和泛型带来的优势之一。
      【解决方案5】:

      您基本上是在编写自己的列表,但效率较低。

      List 在内部执行您所描述的操作,但在性能方面存在很大差异。

      当它重新分配其内部数组时,它不只是添加一个新元素,它会添加一个块。这样,未来的添加并不总是需要重新分配。这是列表的“容量” - 以及为什么列表容量总是 >= 列表的大小。

      如果你必须这样做,我建议你做类似的事情。但是,切换到 List 会是更好的选择。

      【讨论】:

        【解决方案6】:

        您可以做的任何使数组更像ArrayListList&lt;T&gt; 的操作只会导致您最终重新实现部分(或全部)这些类。正如其他答案所述,最好的方法是使用内置类。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-04-15
          • 2020-04-09
          • 2022-01-05
          • 2010-11-30
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多