2

我最近在这里回答了一个问题,由成员@dtb 编辑。

在c#中用0-9之间的唯一随机数填充数组

问题涉及使用 Random() - 并且说成员编辑了我的答案以避免这种常见的陷阱(正如他所说)

我的原始代码孤立地不容易受到此问题的影响,如下所示:

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

答案已被编辑,因为它的意图似乎是在循环中调用该函数 - 这会使代码易受攻击 - 它本质上被更改为:

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

我的直接想法是——这只是将维护 Random 实例的负担推到了更高的堆栈上——如果有问题的程序员不理解它是如何实现的,他们仍然会陷入这个陷阱。

我想我的问题是 - 为什么 .Net 中的 Random() 不以与 Javascript 中相同的方式实现,例如 - 使用一个静态的全局 Random() (比如说,每个 AppDomain?)?自然地,您仍然可以提供更明确的重载/方法,将当前时间用作种子,用于需要控制种子的极少数情况。

当然,这将避免这个非常常见的陷阱。谁能告诉我.Net方法的好处?

编辑:我知道控制种子很重要 - 但是,默认情况下强制执行似乎是一个奇怪的选择。如果有人想控制种子,他们很可能知道自己在做什么。

干杯。

4

2 回答 2

5

因为这种方式可以控制多个随机生成源。通过为每个实例设置相同的种子,您可以根据需要生成相同的序列。有时您不希望其他操作影响您的数字流。

想想一个游戏:每一个随机都是从一个种子数产生的,所以如果你保存玩家输入和随机种子,你就可以从头到尾重现整个游戏。但是,如果您在播放过程中生成随机(例如粒子)或其他不相关但随机的东西,您也不想保存这些。最简单的方法是声明两个随机的,一个用于重要的事情,另一个用于其他所有事情。但这只是一个例子。

因此,您可以根据需要自由声明随机序列,如果您想以这种方式使用它,则无需使用技巧。

于 2012-05-22T09:56:10.063 回答
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; } }
}
于 2012-05-22T09:56:20.843 回答