2012-05-22 9 views
2

Недавно я ответил на вопрос, который был отредактирован членом @dtb.Почему Random() реализован таким образом в .Net?

filling a array with uniqe random numbers between 0-9 in c#

вопрос предусматривал использование Random() - и сказал член редактировал свой ответ, чтобы избежать этого common pitfall (как он выразился)

Мой исходный код не был уязвим к этому вопросу в изоляции, как это было следующим образом:

public void DoStuff() 
{ 
    var rand = new Random(); 
    while() {} //Inner loop that uses 'rand' 
} 

ответ был отредактирован, как оказалось намерение было вызвать функцию в цикле - который сделал бы код уязвимой - она ​​была изменена по существу:

public void DoStuff(Random R) 
{ 
    while() {} //Inner loop that uses 'rand' 
} 

Моя немедленная мысль была - это просто протолкнул бремя поддержания случайный экземпляр дальше вверх по стеку - и если программист в вопросе doen't понять, как это будет реализовано, они все равно попадают в эту ловушку ,

Я предполагаю, что мой вопрос - почему это не Random() в .Net реализовано так же, как в Javascript, например, с одним статическим глобальным Random() (Say, per AppDomain?)? Естественно, вы все же можете предоставить более явные перегрузки/методы, которые используют текущее время в качестве семени, в очень редких случаях, когда вам нужно управлять семенем.

Несомненно, это позволило бы избежать этой общей ошибки. Кто-нибудь может рассказать мне о преимуществах подхода .Net?

EDIT: Я понимаю, что контроль над семенем важен - однако, соблюдение этого значения по умолчанию представляется странным выбором. Если кто-то хочет взять под контроль семена, вероятно, они знают, что они делают.

Cheers.

+2

'Random' класс. Как у вас будет глобальный генератор, который охватывает машины, домены приложений и т. Д. ...? – Oded

+0

Возможный дублированный вопрос, http://stackoverflow.com/questions/4933823/class-system-random-why-not-static –

+0

Инициализация «Случайного» может иметь накладные расходы, которые не следует страдать, если они не намерены ее использовать. – Jon

ответ

5

Потому что таким образом вы можете управлять несколькими источниками случайного генерации. Установив одно и то же семя для каждого экземпляра, вы можете сгенерировать одну и ту же последовательность, если вам это нужно. И иногда вы не хотите, чтобы другие действия влияли на ваш поток чисел.

Подумайте, игра: каждое случайное генерируется из числа семян, поэтому, если вы сохраните вход игрока и случайное семя, вы можете воспроизвести всю игру от начала до конца. Но если вы генерируете случайные, например, частиц или других нерелевантных, но случайных вещей во время игры, вы тоже не хотите их спасать. Самый простой способ - объявить два случайных, один для важных вещей и другой для everithing else. Но это всего лишь один пример.

Таким образом, у вас есть свобода объявлять случайный секвенс на основе ваших потребностей, и вам не нужно использовать трюки, если вы хотите использовать его таким образом.

5

Решение .NET более гибкое, чем одно, включающее в себя один глобальный генератор. Он позволяет каждой части вашего приложения создавать и использовать независимые последовательности повторяемых псевдослучайных чисел, что жизненно важно для целей отладки. Отладочный код, основанный на псевдослучайных числах, не представляет интерес для начала; когда один и тот же генератор получает доступ из разных частей кода, становится невозможным.

В то же время, если вы хотите иметь общий экземпляр Random, вы можете легко сделать его доступным для вашего приложения с помощью нескольких строк кода:

// !!! This is not thread safe!!! 
static class RandomHelper { 
    private static readonly Random rnd = new Random(); 
    public static Random Instance {get { return rnd; } } 
} 
+0

Конечно - это хорошо. Думаю, мой вопрос может быть уточнен: почему поведение * по умолчанию * более эзотерическое. –

+1

@DaveBish Моя догадка так же хороша, как и все остальные, но я подозреваю, что это делается для того, чтобы заставить программистов сделать сознательный выбор общего экземпляра: как только этот выбор сделан, трудно вернуться к нескольким экземплярам, ​​поэтому архитекторы .NET не хотели делать этот выбор для программистов. – dasblinkenlight

+3

Предупреждение любому, у кого возникает желание скопировать ваш примерный код verbatim ... Класс «Random» не является потокобезопасным, поэтому любой, кто использует «RandomHelper» в многопоточной среде, например ASP.NET, скорее всего, станет ужасно сломанные результаты. (Я предполагаю, что вы уже знаете это, но я также уверен, что другие этого не знают.) – LukeH

Смежные вопросы