繁体   English   中英

IEnumerable.ToList()的影响

[英]Impact of IEnumerable.ToList()

我只是想知道在C#中的IEnumerable上调用.ToList()时会发生什么。 这些项目是否实际上被复制到堆上的全新重复项目,或者新列表是否只是引用堆上的原始项目?

我想知道因为有人告诉我调用ToList是昂贵的,而如果只是将现有对象分配给新列表,那就是轻量级调用。

我写过这个小提琴https://dotnetfiddle.net/s7xIc2只是检查哈希码足以知道吗?

IEnumerable不必包含任何内容的列表。 它可以(并且经常会)在请求时解析每个当前项目

另一方面, IList是所有项目的完整内存副本。

所以答案是......这取决于。 什么是支持你的IEnumerable? 如果它的文件系统然后是,则调用.ToList可能非常昂贵。 如果它已经是一个内存列表,那么不,调用.ToList不会非常昂贵。

举个例子,假设您创建了一个IEnumerable,每次生成并返回一个随机数.Next被调用。 在这种情况下,调用IEnumerable上的.ToList将永远不会返回,并最终会抛出Out Of Memory异常。

但是,IEnumerable的数据库对象具有有限的边界(通常是:)),只要所有数据都适合内存,调用.ToList就完全合适了。

这是ToList的一个版本:

public static List<TSource> ToList<TSource>(this IEnumerable<TSource> source)
{
    if (source == null) throw Error.ArgumentNull("source");
    return new List<TSource>(source);
}

它从源代码创建一个新列表,这里是构造函数:

// Constructs a List, copying the contents of the given collection. The
// size and capacity of the new list will both be equal to the size of the
// given collection.
// 
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);                                    
            }
        }
    }
}

它复制项目。

代码来自这里: referencesource.microsoft.com

ToList()创建一个新的List对象,该对象将包含对原始对象的引用或对象的副本(如果它们是struct

例如,int的列表将是完整副本。 “产品”列表仅指产品,而非完整副本。 如果修改了原件,则还会修改列表中的产品。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM