Taking the following code, Resharper tells me that voicesSoFar and voicesNeededMaximum cause “access to a modified closure”. I read about these but what puzzles me here is that Resharper suggests fixing this by extracting the variables to right before the LINQ query. But that is where they are already!
Resharper stops complaining if I merely add int voicesSoFar1 = voicesSoFar right after int voicesSoFar = 0. Is there some weird logic I do not understand that makes Resharper’s suggestion correct? Or is there a way to safely “access modified closures” in cases like these without causing bugs?
// this takes voters while we have less than 300 voices
int voicesSoFar = 0;
int voicesNeededMaximum = 300;
var eligibleVoters =
voters.TakeWhile((p => (voicesSoFar += p.Voices) < voicesNeededMaximum));
You have a very nasty problem that arises from mutating an outer variable to the lambda expression. The problem is this: if you try to iterate
eligibleVoterstwice (foreach(var voter in eligibleVoters) { Console.WriteLine(voter.Name); }and immediately after (foreach(var voter in eligibleVoters) { Console.WriteLine(voter.Name); }) you will not see the same output. That is just not right from a functional programming perspective.Here is an extension method that will accumulate until some condition on the accumulator is true:
Usage:
Thus the above says accumulate voices while we have accumulated less than 300 votes.
Then with:
Output is: