Генерация случайных чисел - тот же номер возвращен

Возможные дубликаты:
С# - повторное повторение одного и того же случайного числа
Генератор случайных чисел не работает так, как я планировал (С#)

У меня есть метод, который строит очередь ints:

public Queue<int> generateTrainingInts(int count = 60)
    {
        Queue<int> retval = new Queue<int>();

        for (int i = 0; i < count; i++)
        {
            retval.Enqueue(JE_Rand.rInt(2001, 100));
        }

        return retval;
    }

JE_Rand.rInt() - это просто функция, которая делегирует функцию класса Random:

public static int rInt(int exclUB, int incLB = 0)
    {
        Random rand = new Random(DateTime.Now.Millisecond);
        int t = rand.Next(incLB, exclUB);
        rand = null;            
        return t;
    }

Но когда я вызываю generateTrainingInts, одно и то же число помещается в очередь каждый раз. Однако, если я изменяю rInt на использование статического экземпляра класса Random, вместо локального экземпляра (с областью действия, как он определен выше), то он работает корректно (enqueue random integers). Кто-нибудь знает, почему это происходит?

Изменить: Дорогой Ответчик, который не прочитал мой вопрос полностью,   Как некоторые из вас отметили, я ищу хорошее объяснение, почему это происходит. Я не ищу решение проблемы с тем же номером, потому что я уже исправил это, как я сказал выше. Спасибо за ваш энтузиазм, хотя:) Я просто хочу понять такие вещи, потому что моя первая реализация поняла меня концептуально.

Ответ 1

Вам нужно сохранить тот же объект Random. Поместите его вне своего статического метода в качестве статического члена

private static Random rand = new Random();

public static int rInt(int exclUB, int incLB = 0)
{
    int t = rand.Next(incLB, exclUB);
    return t;
}

Edit
Причина - конечное разрешение часов, используемых для инициализации Random. Последующие инициализации Random получат одну и ту же начальную позицию в случайной последовательности. При повторном использовании одного и того же Random всегда генерируется следующее значение в случайной последовательности.

Ответ 2

Попробуйте следующий код, и я думаю, вы поймете, почему:

void PrintNowAHundredTimes()
{
    for (int i = 0; i < 100; ++i)
    {
        Console.WriteLine(DateTime.Now);
    }
}

Объекты Random получают одно и то же семя снова и снова. Это связано с тем, что зернистость системного времени, возвращаемого DateTime.Now, является, конечно, конечной. Например, на моей машине значение изменяется только каждые ~ 15 мс. Таким образом, последовательные вызовы в течение этого периода времени возвращаются в одно и то же время.

И, как я подозреваю, вы уже знаете, два объекта Random, инициализированные с тем же начальным значением, будут генерировать идентичные случайные последовательности. (Вот почему он назывался псевдослучайным, технически.)

Вы также должны знать, что даже если было бы целесообразно создать экземпляр нового объекта Random локально в вашем методе, установка его в null все равно будет бесполезной (после выхода метода больше не будет ссылок на объект в любом случае, так что это будет сбор мусора независимо).

Ответ 3

public class JE_Rand
{
   private static Random rand= new Random(DateTime.Now.Millisecond);

    public static int rInt(int exclUB, int incLB = 0)
    {
        int t = rand.Next(incLB, exclUB);
        return t;
    }
}