如何生成随机值,这些值不会在"运行"数字中给我相同的值?

Ale*_*sky 0 .net c# random

您好,我编写了这个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];
      }
}
Run Code Online (Sandbox Code Playgroud)

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

[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);
        }
Run Code Online (Sandbox Code Playgroud)

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

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

谢谢 :)

Mar*_*ers 10

您不应该调用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];
      }
}
Run Code Online (Sandbox Code Playgroud)

这样做的另一个好处是可以使代码更易于测试,因为您可以传入一个随机播种到您选择的值,以便您的测试可重复.