LINQ枚举查询是否返回副本或引用



我想在C++中复制C#中的SkipTake,以便创建切片。类似于:

std::vector<int> numbers = { 59, 82, 70, 56, 92, 98, 85 };
auto slice = grades.skip(3).take(2); // {56, 92}

在检查了切片在JS和Golang中的工作方式后,我基本上明白了他们更喜欢影子复制而不是深度复制。我理解分配新内存但拥有独立数据和只复制引用来拥有相关数据之间的权衡。

现在,我也检查了Skip和Take,但我找不到他们使用的是哪一个。

简而言之,它们在开始和结束时是否返回某种枚举器?还是他们创造了一个全新的IEnumerable?

编辑

所以,我不知道我们可以访问源代码(在评论中提到(。显然,它返回了一个迭代器:

public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count) {
if (source == null) throw Error.ArgumentNull("source");
return SkipIterator<TSource>(source, count);
}
}

LINQ的Skip、Take等方法不返回任何集合。它们返回IEnumerable接口,该接口允许从底层源获取下一个元素。这就是延迟加载的概念。SkipTake在您需要结果之前不会实际过滤您的集合。

可以使用方法ToArrayToList将IEnumerable中的所有元素复制到某个集合中。

供参考的文章:https://odetocode.com/blogs/scott/archive/2008/10/01/lazy-linq-and-enumerable-objects.aspx

Linq只为基类型(int,string,double-ecc..(返回新的引用。IEnumerable将是初始列表的同一实例,您必须调用ToList o ToArray才能创建新的集合。

最新更新