0

对于某些 TreeView,我想测试项目的背景属性的许多值。

所以我现在有一棵树,里面有 200 个项目。

这些是可能的值:

public enum EnumItemState
{ 
    Default,
    Red,
    Green,
    Yellow,
}

现在我想在视图中快速测试不同的值,所以我写了这段代码:

    private EnumItemState GetRandomItemState()
    {

        var rand = new Random();

        var val = rand.Next(0, 3);

        switch (val)
        {
            case 0:
                {
                    return EnumItemState.Red;
                }
            case 1:
                {
                    return EnumItemState.Green;
                }
            case 2:
                {
                    return EnumItemState.Yellow;
                }
            default:
                {
                    return EnumItemState.Default;
                }
        }
    }

但这根本不是随机的。一次运行的所有值都相同。

在我的“随机”方法中的某处有断点,我会得到不同的、“更随机”的结果。

这里发生了什么?

如何获得更好的随机结果?

是不是一些优化,所以我所有的随机数都是用相同的时间种子创建的,因此得到相同的结果?

4

2 回答 2

1

每次调用使用相同值(基于当前时间)播种的方法时,您都会创建一个新的 Random 对象,因此您会不断获得相同的随机值。

改为这样做:

void CallingMethod()
{
    Random rnd = new Random();

    for (int i = 0;i < 200;++i)
        EnumItemState state = GetRandomItemState(rnd);
}

private EnumItemState GetRandomItemState(Random rnd)
{
    // Same code you had here, but don't create new instance of Random
}
于 2013-03-20T20:03:51.573 回答
0

我将假设您在一个紧密的循环中非常频繁地调用它(即,调用之间几乎没有时间)

的默认 ctorRandom如下所示:

public Random() : this(Environment.TickCount)
{
}

看到了Environment.TickCount吗?如果您Random非常快速地尝试新建多个实例(即,在该滴答计数更改之前),您将有效地获得完全相同的随机数序列 - 因此是“PseudoRandom”。

您可以执行以下操作之一:

  • 在通话之间等待一段时间
  • 手动将种子传递给ctor
  • System.Security使用命名空间中的 prngs
于 2013-03-20T20:04:52.560 回答