Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Does LINQ Enumerable query return copy or reference?

Tags:

c#

linq

I want to replicate the Skip and Take from C# in C++ in order to create slices. Something like:

std::vector<int> numbers = { 59, 82, 70, 56, 92, 98, 85 };

auto slice = grades.skip(3).take(2); // {56, 92}

After checking how slices work in JS and Golang, I basically understand that they preferred shadow copy over deep copy. I understand the trade off between allocating new memory but having independent data and having related data by copying only the reference.

Now, I also checked Skip and Take but I can't find which one they use.

In short, do they return some kind of Enumerator at the start and at the end? Or do they create an entirely new IEnumerable?

Edit

So, I didn't know we can access the source code (mentioned in the comments). And apparently it returns an iterator:

public static IEnumerable<TSource> Skip<TSource>(this IEnumerable<TSource> source, int count) {
   if (source == null) throw Error.ArgumentNull("source");
      return SkipIterator<TSource>(source, count);
   }
}
like image 697
Clément Jean Avatar asked May 30 '26 09:05

Clément Jean


2 Answers

Skip, Take and other method of LINQ does not return any collection. They return IEnumerable interface that allows to get next element from underlying source. This is concept of lazy loading. Skip and Take does not actualy filter your collection untill you need the result.

You can copy all elements from IEnumerable to some collection with method ToArray or ToList.

Artile for reference: https://odetocode.com/blogs/scott/archive/2008/10/01/lazy-linq-and-enumerable-objects.aspx

like image 187
Backs Avatar answered Jun 01 '26 23:06

Backs


Linq returns new references only for base types (int, string, double ecc..). The IEnumerable will be same instance of initial list, you have to call ToList o ToArray to create new collection.

like image 40
Andrea Avatar answered Jun 02 '26 01:06

Andrea