I had a complex scenario when I was using a yield
with random numbers and faced some strange behavior.
I tried to simplify my case with a simpler code example and managed to reproduce it with a very simple code.
In the following code, I would expect to get "Equal!" printed, but actually, it is not.
using System;
using System.Collections.Generic;
using System.Linq;
namespace ConsoleAppSample
{
static class Program
{
public static void Main(string[] args)
{
IEnumerable<int> randomNumbers = GetRandomNumbers();
int firstRandomnumber = randomNumbers.First();
if (firstRandomnumber == randomNumbers.First())
{
Console.WriteLine("Equal!");
}
}
private static readonly Random random = new Random();
private static readonly object syncLock = new object();
public static int RandomNumber(int min, int max)
{
lock (syncLock)
{
return random.Next(min, max);
}
}
private static IEnumerable<int> GetRandomNumbers(int loopCount = 2)
{
for (int i = 0; i < loopCount; i++)
{
yield return RandomNumber(int.MinValue, int.MaxValue);
}
}
}
}
I tried to debug it and found even something weirder. While holding the breakpoint at the same place the values of the randomNumbers
variable change every moment.
In the following image, you can see the watch shows different numbers for the same variable.
If I change the GetRandomNumbers()
method implementation to insert values into a list and return the list (without using yield), it will work fine.
I try to understand why it works this way? I guess it is related to the way random generates numbers based on the computer clock and the way yield
works, but I am not sure.