【问题标题】:Quick way to convert a Collection to Array or List?将集合转换为数组或列表的快速方法?
【发布时间】:2015-06-18 01:41:57
【问题描述】:

对于每个 *CollectionHtmlNodeCollectionTreeNodeCollectionCookieCollection 等)类实例,我需要传递给只接受数组或列表的方法(不应该有接受 @例如,TreeView 中的 987654326@?)我必须编写这样的扩展方法:

public static TreeNode[] ToArray(this TreeNodeCollection nodes)
        {
            TreeNode[] arr = new TreeNode[nodes.Count];
            nodes.CopyTo(arr, 0);
            return arr;
        }

或遍历整个集合,将项目添加到输出列表,然后将输出列表转换为数组:

 public static TreeNode[] ToArray(this TreeNodeCollection nodes)
        {
      var output = new List<TreeNode>();
            foreach (TreeNode node in nodes)
                output.Nodes(node);
            return output.ToArray();
 }

所以,我的问题是: 我经常需要这种扩展方法。如果列表很大,它可能会分配大量内存,就像通常一样。为什么我不能只获取此*Collection 类使用的内部数组的引用(而不是复制),这样我就无需使用该扩展并执行此内存分配?甚至提供ToArray() 方法。我们不需要知道它的内部实现或在最后一种情况下使用的数组。

【问题讨论】:

  • I need to pass to a method which accepts only an array or list 为什么不IEnumerable&lt;T&gt; ?您可以轻松传递treeNodeCollection.Cast&lt;TreeNode&gt;() 为ex。
  • 使用IEnumerable&lt;T&gt;。如果您需要数组,请使用 collection.Cast&lt;TreeNode&gt;().ToArray() 并完全摆脱您的扩展方法。
  • .Cast&lt;&gt;() 真的很好...collection.Cast&lt;TreeNode&gt;().ToArray() 与我的.ToArray() 扩展名有什么不同(当然,除了它是本地的)?

标签: c# arrays collections


【解决方案1】:

所有 BCL 集合类隐藏其内部数组的原因是出于“API 友好”的原因。内部数组可以在需要增长或缩小的情况下进行更改。然后,任何引用旧数组的用户代码都会变得混乱。此外,用户代码可能会访问对集合无效的数组索引。如果您有一个ListCapacity = 16 &amp;&amp; Count == 10,那么您可以访问索引15 处的内部数组,该列表通常不允许这样做。

这些问题使 API 难以使用。它们会导致支持票证和 Stack Overflow 问题。

删除现有代码并将其替换为:

TreeNodeCollection nodes;
var myArray = nodes.Cast<TreeNode>().ToArray();

如果你觉得有必要,你可以把它变成一个扩展方法。将参数键入为IEnumerable(无泛型)。为什么 BCL 中的现有集合没有升级到实现IEnumerable&lt;T&gt;,这对我来说是个谜。这就是您需要Case 的原因。 I just created a User Voice item for this.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-19
    • 1970-01-01
    • 2011-12-05
    • 2011-07-05
    • 1970-01-01
    • 2013-09-15
    • 1970-01-01
    • 2016-01-31
    相关资源
    最近更新 更多