Reputation: 1021
For some reason the 2nd list List2
isn't being populated, when it should.
var List1 = new List<object1>();
//populated List1 here
var List2 = new List<object1>();
List1.OrderByDescending(o => o.Cnt).Take(10).Select(s =>
{
List2.Add(s);
return s;
});
List2
should have 10 entries by now, but doesn't? How is it possible?
Upvotes: 1
Views: 71
Reputation: 13224
This happens, because enumerables are lazily evaluated. The code in the Select
will only be executed when you start iterating over the enumerable (i.e. consume it).
This allows you for instance to create enumerables that (potentially) return an infinite number of results, like in:
public static class MyInfiniteEnumerable
{
public static IEnumerable<int> GetIt()
{
var x = 0;
while (true)
yield return x + 1;
}
}
In your code, to start filling the List2
you will need to "consume" the IEnumerable
by iterating over its elements until it is done. For instance like this:
var myEnum = List1.OrderByDescending(o => o.Cnt).Take(10).Select(s =>
{
List2.Add(s);
return s;
});
foreach (var e in myEnum)
; // do nothing, just iterate.
More useful would be:
var list2 = List1.OrderByDescending(o => o.Cnt).Take(10).ToList();
Or
list2.AddRange(List1.OrderByDescending(o => o.Cnt).Take(10));
Upvotes: 2
Reputation: 9500
It's a lazy evaluation problem. You are not doing anything with the Select, so the adds are not happening. If you do this, it will work:
var resultList = List1.OrderByDescending(o => o.Cnt).Take(10).Select(s =>
{
List2.Add(s);
return s;
}).ToList(); //Now List2 has 10 items.
Upvotes: 2
Reputation: 103447
It's not working because LINQ expressions are lazily evaluated. That Select
function is not actually executed until you iterate over it, which you never do.
If you add a .ToList();
to the end, you should see it working.
However, that is not the idiomatic way to do what you're trying to do. As a commenter suggested, something like this would be much better:
var List2 = List1.OrderByDescending(o => o.Cnt).Take(10).ToList();
Or to add the values to an already populated list,
List2.AddRange(List1.OrderByDescending(o => o.Cnt).Take(10));
Upvotes: 2
Reputation: 12196
It's because Linq static functions are using Lazy execution that means they only executes the code when they need to.
That means only when you use methods like Count()
, ToList()
etc' .NET will give you the result you desire and start execute the code you wanted.
You can achieve the result you want through appending .ToList()
to the end of your .Select()
.
But a better solution will be using other means.
Upvotes: 2