My code below finds all prime numbers below number by creating a list of primes and checking to see if the next potential prime is evenly divisible by any primes in the list.
I’m trying to learn the ins and outs of yield return. Right now I have a List<int> primes that I use inside the function. But I’m returning the same data via yield return. So my question is
Can I access the IEnumerable< int > from inside the function as I am creating it? So I can remove the List< int > primes altogether.
/// <summary>
/// Finds all primes below <paramref name="number"/>
/// </summary>
/// <param name="number">The number to stop at</param>
/// <returns>All primes below <paramref name="number"/></returns>
private static IEnumerable<long> PrimeNumbers(long number)
{
yield return 2;
List<long> primes = new List<long>(2);
for(long num = 3; num < number; num += 2)
{
//if any prime lower then num divides evenly into num, it isn't a prime
//what I'm doing now
if(!primes.TakeWhile(x => x < num).Any(x => num % x == 0))
{
primes.Add(num);
yield return num;
}
//made-up syntax for what I'd like to do
if(!this.IEnumerable<long>
.TakeWhile(x => x < num).Any(x => num % x == 0))
{
yield return num;
}
}
}
No, you cannot do that. The compiler builds a state machine to implement
yield return, and the calling code that enumerates through your enumerable is as much a part of its working as your code is. The compiler builds a hidden object that stores the current state of your code, including its call stack and locals, and it calls different pieces of your method as the caller invokesCurrentandMoveNext. Trying to enumerate your object from the beginning while another enumeration is in progress would mess up the ongoing enumeration, which would not be good.In this particular case, you don’t want it to happen either: the implementation of
yield returndoes not store the values that you produce, so if even if you could access your ownIEnumerablewhile enumerating, it would recursively call back itself multiple times to produce each new item, so it would take you ridiculously long time to produce even a moderate number of primes.