ToList 有容量?

Ser*_*pov 5 c#

当我们.ToList()为 an 执行时IEnumerable,列表可能会在扫描 时重新分配,IEnumerable因为它预先不知道大小。如果已知大小,是否有一种简单的方法可以避免性能损失?List使用所需容量初始化 a然后将其复制IEnumerable到其中的效果如何?理想情况下像.ToList(capacity)(不存在)一样简单。

das*_*ght 10

在当容量的一部分的情况下IEnumerable<T>,这也是一个ICollection<T>,该库将分配在正确的能力。

这是 的参考实现List<T>(IEnumerable<T> source),在调用时会调用ToList()

public List(IEnumerable<T> collection) {
    if (collection==null)
        ThrowHelper.ThrowArgumentNullException(ExceptionArgument.collection);
    Contract.EndContractBlock();

    ICollection<T> c = collection as ICollection<T>;
    if( c != null) {
        int count = c.Count;
        if (count == 0) {
            _items = _emptyArray;
        } else {
            _items = new T[count];
            c.CopyTo(_items, 0);
            _size = count;
        }
    } else {                
        _size = 0;
        _items = _emptyArray;
        // This enumerable could be empty.  Let Add allocate a new array, if needed.
        // Note it will also go to _defaultCapacity first, not 1, then 2, etc.

        using(IEnumerator<T> en = collection.GetEnumerator()) {
            while(en.MoveNext()) {
                Add(en.Current);                                    
            }
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

请注意构造函数在collection实现时的行为ICollection<T>:它不是迭代内容并Add为每个项目调用,而是分配内部_items数组,并将内容复制到其中而不重新分配。

在容量嵌入到类实现中的情况下IEnumerable<T>,您可以使用标准方法的组合轻松地自己定义一个:

public static class ToListExtension {

    public static List<T> ToList<T>(this IEnumerable<T> source, int capacity) 
    {
        var res = new List<T>(capacity);
        res.AddRange(source);
        return res;
    }

}
Run Code Online (Sandbox Code Playgroud)