Strange Enumerabl.Select behaviour

  • Thread starter Thread starter Oleg Subachev
  • Start date Start date
O

Oleg Subachev

I expected that the following code:

Random RND = new Random();
var S = Enumerable.Range( 1, 2 ).Select( i => RND.NextDouble() );
foreach ( var V in S )
Console.WriteLine( V );
Console.WriteLine();
foreach ( var V in S )
Console.WriteLine( V );

prints the same sets of doubles.
But the sets are different.

In my case:
0,305861282770457
0,0789059219318004

0,828014308040968
0,46924011291435

Why S does not keep the values between foreach calls ?


Oleg Subachev
 
Every time the data is projected, the selector (i => RND.NextDouble())
is called. That means that RND.NextDouble() gets called 4 times, not
2. You can see this by adding a line:

var S = Enumerable.Range(1, 2).Select(i => {
Trace.WriteLine("Selector invoked");
return RND.NextDouble(); });

In this *particular* case, adding .ToList() to the "S" line would
force it to store the values when it has evaluated them, i.e.

var S = Enumerable.Range( 1, 2 ).Select( i =>
RND.NextDouble() ).ToList();

This would then only have 2 selector invokes. But in the *general*
case this will force loading all the data, so only makes sense if you
know the size of the data.

Marc
 
Oleg Subachev said:
I expected that the following code:

Random RND = new Random();
var S = Enumerable.Range( 1, 2 ).Select( i => RND.NextDouble() );
foreach ( var V in S )
Console.WriteLine( V );
Console.WriteLine();
foreach ( var V in S )
Console.WriteLine( V );

prints the same sets of doubles.
But the sets are different.

In my case:
0,305861282770457
0,0789059219318004

0,828014308040968
0,46924011291435

Why S does not keep the values between foreach calls ?

Why would you expect it to? That would be a serious design flaw IMO, as
that would mean you'd have to store all the data generated by the query
- meaning that you couldn't handle large sequences of data.

Queries are executed each time you enumerate them.
 
Why S does not keep the values between foreach calls ?
Why would you expect it to? That would be a serious design flaw IMO, as
that would mean you'd have to store all the data generated by the query
- meaning that you couldn't handle large sequences of data.

Queries are executed each time you enumerate them.

Jon !
Thanks for clarification.
I still out of habit think about queries as about variables.

Will you cover such matter in your book ?


Oleg Subachev
 
Oleg Subachev said:
Jon !
Thanks for clarification.
I still out of habit think about queries as about variables.

And of course they are - but they're *sources* of data rather
containing the data themselves.
Will you cover such matter in your book ?

I wouldn't like to say whether I specifically spell out that point, but
I would hope that by the time a reader had finished chapter 11, they'd
understand it :)
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Back
Top