将集合转换为数组或列表的快速方法?
Quick way to convert a Collection to Array or List?
对于每个 *Collection
(HtmlNodeCollection
、TreeNodeCollection
、CookieCollection
等)class 我需要传递给只接受一个方法的实例数组或列表(例如,不应该有一个在 TreeView
中接受 TreeNodeCollection
的方法?)我必须写一个这样的扩展方法:
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
classes 使用的内部数组的引用(而不是复制),这样我就不需要使用该扩展并执行此内存分配?甚至提供 ToArray()
方法。我们不需要知道最后一个案例中使用的内部实现或数组。
所有 BCL 集合 类 隐藏其内部数组的原因是 "API niceness"。内部数组可以在需要增长或收缩时发生变化。然后,任何引用旧数组的用户代码都会变得混乱。此外,用户代码可能会访问对集合无效的数组索引。如果你有一个 List
和 Capacity = 16 && Count == 10
,然后你可以访问索引 15 处的内部数组,这通常是列表不允许的。
这些问题使 API 难以使用。它们会导致支持票和 Stack Overflow 问题。
删除现有代码并将其替换为:
TreeNodeCollection nodes;
var myArray = nodes.Cast<TreeNode>().ToArray();
如果您觉得有必要,可以将其作为扩展方法。将参数键入 IEnumerable
(无泛型)。为什么 BCL 中的现有集合没有升级以实现 IEnumerable<T>
,这对我来说是个谜。这就是为什么你需要 Case
。 I just created a User Voice item for this.
对于每个 *Collection
(HtmlNodeCollection
、TreeNodeCollection
、CookieCollection
等)class 我需要传递给只接受一个方法的实例数组或列表(例如,不应该有一个在 TreeView
中接受 TreeNodeCollection
的方法?)我必须写一个这样的扩展方法:
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
classes 使用的内部数组的引用(而不是复制),这样我就不需要使用该扩展并执行此内存分配?甚至提供 ToArray()
方法。我们不需要知道最后一个案例中使用的内部实现或数组。
所有 BCL 集合 类 隐藏其内部数组的原因是 "API niceness"。内部数组可以在需要增长或收缩时发生变化。然后,任何引用旧数组的用户代码都会变得混乱。此外,用户代码可能会访问对集合无效的数组索引。如果你有一个 List
和 Capacity = 16 && Count == 10
,然后你可以访问索引 15 处的内部数组,这通常是列表不允许的。
这些问题使 API 难以使用。它们会导致支持票和 Stack Overflow 问题。
删除现有代码并将其替换为:
TreeNodeCollection nodes;
var myArray = nodes.Cast<TreeNode>().ToArray();
如果您觉得有必要,可以将其作为扩展方法。将参数键入 IEnumerable
(无泛型)。为什么 BCL 中的现有集合没有升级以实现 IEnumerable<T>
,这对我来说是个谜。这就是为什么你需要 Case
。 I just created a User Voice item for this.