[英]C# Why IEnumerable and IEnumerable.ToList() print their result is difference?
[英]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.