【问题标题】:Is converting this ArrayList to a Generic List efficient?将此 ArrayList 转换为通用列表有效吗?
【发布时间】:2011-02-28 20:09:51
【问题描述】:

我正在编写的代码从非托管代码接收一个 ArrayList,这个 ArrayList 将始终包含一个或多个 Grid_Heading_Blk 类型的对象。我考虑过将此 ArrayList 更改为通用列表,但我不确定转换操作是否会如此昂贵,以至于抵消使用通用列表的好处。目前,在将 ArrayList 传递给将使用它的类之后,我正在运行 foreach (Grid_Heading_Blk in myArrayList) 操作来处理 ArrayList 的内容。

我应该将 ArrayList 转换为通用类型列表吗?如果是这样,最有效的方法是什么?

【问题讨论】:

    标签: .net generics performance arraylist boxing


    【解决方案1】:

    这是一种从 ArrayList 创建通用列表的高效方法。

    List<Grid_Heading_Blk> myList = new List<Grid_Heading_Blk>(source.Count);
    myList.AddRange(source.OfType<Grid_Heading_Blk>());
    

    通过调用接受 int 的 构造函数,后备存储仅分配一次。

    与往常一样,您应该使用您通常使用的任何工具来衡量性能。

    【讨论】:

    • 谢谢大家。这里有很多很好的答案。虽然性能/效率肯定是一个关键问题,但我可能一直低估了类型化结构提供的可读性。如果其他人最终维护我的代码,我希望它尽可能清楚我在做什么。
    【解决方案2】:

    我经常使用这个清单来评估像你这样的问题:

    1. 改正
    2. 说清楚
    3. 简明扼要
    4. 提高效率

    List&lt;Grid_Heading_Blk&gt;ArrayList更能揭示意图。所以,不考虑效率,第2项已经大获全胜了。

    要将ArrayList 转换为List&lt;&gt;,您必须遍历ArrayList 一次并强制转换每个元素。 foreach 正在执行隐式转换,因此开销仅在额外的迭代中。

    对序列进行两次迭代会将性能从O(n) 提高到O(2n),仍然是O(n)(对性能而言,重要的是大小,而不是值)。因此,您可以认为这种变化是良性的。

    但是,如果实际上所有您正在运行foreach,您应该直接使用ArrayList - 将其更改为List&lt;&gt; 不会让您获得更多的表达能力。

    【讨论】:

      【解决方案3】:

      为什么你需要转换ArrayList?老实说,您的 foreach 循环似乎可以解决问题。是的,正如上面 Kevin 所说,您需要支付的唯一惩罚是拆箱 - 但就目前而言,它是非常简单的代码,您可能没有足够的网格标题来支付真正的性能损失。

      但是如果你必须转换它我会说,而不是编写你自己的 for 循环来转换为 List 泛型类型,最好使用采用 IEnumerable 类型的构造函数(ArrayList 应该已经实现.)

      List<Grid_Heading_Blk> heading = new List<Grid_Heading_Blk>( arrayList );
      

      【讨论】:

        【解决方案4】:

        使用 ArrayLists 的最大惩罚是装箱。

        使用泛型您可以获得:
        1.编译时安全
        2. 泛型扩展
        3. 取消将列表中的所有内容转换为类型对象的限制。

        这些是您使用它们的优势。它们是优势,但如果您必须从 ArrayList 重新填充泛型,则可能不值得这样做,特别是如果您只是循环遍历列表以获取对象。

        【讨论】:

          【解决方案5】:

          “高效”不是非此即彼的属性。这是相对的,就像一只大老鼠可能不比一头小象大。

          这取决于你在做什么。

          您的里程可能会有所不同,但根据我的经验,虽然 ArrayList 可能比 List&lt;T&gt; “慢”,但我从来没有做这么少,以至于它以任何方式引人注目。

          也就是说,很高兴让编译器为我做类型检查,而且不用强制转换也很好。

          【讨论】:

            【解决方案6】:

            如果对象来自非托管代码,并且您不需要添加或删除对象,则 Grid_Heading_Blk 数组可能比 List 更有效。如果你可以不使用数组,那么使用 for 循环可能会比 foreach 稍快。

            【讨论】:

              【解决方案7】:

              您可以使用Enumerable.OfType(Of TResult) Method过滤所有可以转换为相同类型的arrayList元素

              List<MyClass> typedList = arrayList.OfType<MyClass>().ToList();
              

              (基于http://www.codeproject.com/Tips/68291/Convert-ArrayList-to-a-Generic-List 中的建议)

              【讨论】:

                猜你喜欢
                • 2013-05-14
                • 2013-05-07
                • 2016-07-25
                • 1970-01-01
                • 1970-01-01
                • 1970-01-01
                • 2017-11-15
                • 2017-03-31
                • 2021-09-08
                相关资源
                最近更新 更多