【问题标题】:How to generate random values that don't keep giving me the same value in 'runs' of numbers?如何生成在数字“运行”中不会一直给我相同值的随机值?
【发布时间】:2009-12-13 19:40:35
【问题描述】:

您好,我编写了这个 OneAtRandom() 扩展方法:

public static class GenericIListExtensions
   {
      public static T OneAtRandom<T>(this IList<T> list)
      {
         list.ThrowIfNull("list");
         if (list.Count == 0)
            throw new ArgumentException("OneAtRandom() cannot be called on 'list' with 0 elements");

         int randomIdx = new Random().Next(list.Count);
         return list[randomIdx];
      }
}

使用此单元测试对其进行测试失败:

[Test]
        public void ShouldNotAlwaysReturnTheSameValueIfOneAtRandomCalledOnListOfLengthTwo()
        {
            int SomeStatisticallyUnlikelyNumberOf = 100;
            IList<string> list = new List<string>() { FirstString, SecondString };
            bool firstStringFound = false;
            bool secondStringFound = false;

            SomeStatisticallyUnlikelyNumberOf.Times(() =>
            {
                string theString = list.OneAtRandom();
                if (theString == FirstString) firstStringFound = true;
                if (theString == SecondString) secondStringFound = true;
            });
            Assert.That(firstStringFound && secondStringFound);
        }

似乎int randomIdx = new Random().Next(list.Count);连续100次生成相同的数字,我想可能是因为种子是基于时间的?

我怎样才能让它正常工作?

谢谢:)

【问题讨论】:

    标签: c# .net random


    【解决方案1】:

    您不应该为每次迭代都调用new Random(),因为它会导致它被重新播种并再次生成相同的数字序列。在您的应用程序开始时创建一个 Random 对象并将其作为参数传递给您的函数。

    public static class GenericIListExtensions
    {
          public static T OneAtRandom<T>(this IList<T> list, Random random)
          {
             list.ThrowIfNull("list");
             if (list.Count == 0)
                throw new ArgumentException("OneAtRandom() cannot be called on 'list' with 0 elements");
    
             int randomIdx = random.Next(list.Count);
             return list[randomIdx];
          }
    }
    

    这还具有使您的代码更具可测试性的优点,因为您可以传入一个随机值,该随机值被播种为您选择的值,以便您的测试是可重复的。

    【讨论】:

    • 谢谢。我知道这是 Random() :)
    【解决方案2】:

    没有;它生成相同的数字 100 次,因为您没有播种生成器。

    将“new Random()”移动到构造函数或静态变量中,并使用生成的对象。

    【讨论】:

      【解决方案3】:

      您可以使用基于当前时间的种子来创建Random 的实例。 A sample on MSDN 使用以下代码:

      int randomInstancesToCreate = 4;
      Random[] randomEngines = new Random[randomInstancesToCreate];
      for (int ctr = 0; ctr < randomInstancesToCreate; ctr++)
      {
         randomEngines[ctr] = new Random(unchecked((int) (DateTime.Now.Ticks >> ctr)));
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-11-08
        • 1970-01-01
        • 2021-12-31
        • 1970-01-01
        • 2021-03-01
        相关资源
        最近更新 更多