【问题标题】:How do I generate a random int number?如何生成随机整数?
【发布时间】:2020-08-06 18:00:23
【问题描述】:

如何在 C# 中生成随机整数?

【问题讨论】:

    标签: c# random


    【解决方案1】:

    Random class 用于创建随机数。 (当然是伪随机的。)。

    例子:

    Random rnd = new Random();
    int month  = rnd.Next(1, 13);  // creates a number between 1 and 12
    int dice   = rnd.Next(1, 7);   // creates a number between 1 and 6
    int card   = rnd.Next(52);     // creates a number between 0 and 51
    

    如果您要创建多个随机数,您应该保留Random 实例并重复使用它。如果您创建新实例的时间太接近,它们将产生与随机生成器从系统时钟播种的相同系列的随机数。

    【讨论】:

    • 为了重用它,您可以将rnd 声明为static 和/或在初始化代码时只设置一次。
    • @JuniorM:是的,您可以将其设为静态以重用它,但您必须小心不要从多个线程访问它,因为它不是线程安全的(对于任何不是专门设置为线程安全的类)。
    • 我认为添加免责声明会很有用,即这不是加密安全的,因为这是一个流行的问题,以防万一有人盲目地尝试使用 Random 进行加密...跨度>
    • 优秀的答案。 Random 有一些很好的“增强”,可以让你的随机性更加健壮:ericlippert.com/2019/02/04/fixing-random-part-2codeblog.jonskeet.uk/2009/11/04/revisiting-randomness
    • 如果有帮助,var number = Random.Range(1, 254);来自统一交换:answers.unity.com/questions/308513/random-number-generator.html
    【解决方案2】:

    这个问题看起来很简单,但答案有点复杂。如果你看到几乎每个人都建议使用 Random 类,有些人建议使用 RNG 加密类。但是什么时候选择什么。

    为此,我们需要先了解“随机”一词及其背后的理念。

    我建议您观看此视频,该视频深入探讨了使用 C# https://www.youtube.com/watch?v=tCYxc-2-3fY 的 RANDOMNESS 哲学

    首先让我们了解 RANDOMNESS 的哲学。当我们告诉一个人在红色、绿色和黄色之间进行选择时,内部会发生什么。是什么让一个人选择红色、黄色或绿色?

    一些初步的想法进入决定他选择的人的脑海中,它可以是喜欢的颜色,幸运的颜色等等。换句话说,一些我们在 RANDOM 中称为 SEED 的初始触发器。这个 SEED 是起点,是促使他选择 RANDOM 值的触发器。

    现在,如果 SEED 很容易猜到,那么这些随机数被称为 PSEUDO,而当种子难以猜到时,这些随机数被称为 SECURED random数字。

    例如,一个人根据天气和声音组合选择颜色,那么就很难猜出最初的种子。

    现在让我做一个重要的声明:-

    *“Random”类只生成伪随机数,要生成安全随机数,我们需要使用“RNGCryptoServiceProvider”类。

    Random 类从您的 CPU 时钟中获取种子值,这是非常可预测的。所以换句话说 C# 的 RANDOM 类生成伪随机数,下面是相同的代码。

    var random = new Random();
    int randomnumber = random.Next()
    

    虽然RNGCryptoServiceProvider 类使用操作系统熵来生成种子。操作系统熵是使用声音、鼠标点击和键盘计时、热温度等生成的随机值。下面是相同的代码。

    using (RNGCryptoServiceProvider rg = new RNGCryptoServiceProvider()) 
    { 
        byte[] rno = new byte[5];    
        rg.GetBytes(rno);    
        int randomvalue = BitConverter.ToInt32(rno, 0); 
    }
    

    要了解操作系统熵,请观看 14:30 https://www.youtube.com/watch?v=tCYxc-2-3fY 的此视频,其中解释了操作系统熵的逻辑。因此,简单地说,RNG Crypto 会生成 SECURE 随机数。

    【讨论】:

    • 不应该是你的 byte[5] only [4] 因为 ToInt32 只解析 4 个字节?
    • 了解这些类的位置总是很有帮助的。 System.Security.Cryptography
    • 建议使用RandomNumberGenerator.Create()而不是调用RNGCryptoServiceProvider的构造函数,因为它并非在所有平台上都可用。
    • 我只想准确地说 SecureRandom 是伪随机生成。
    • 由于种子的随机性增加,是否可以在每次需要生成随机数时创建新的 RNGCryptoServiceProvider 对象,或者创建一个 RNGCryptoServiceProvider 对象并在我使用时重用它是否更好需要生成一个随机数,就像使用 Random 类一样?
    【解决方案3】:

    每次您执行new Random() 时,它都会被初始化。这意味着在一个紧密的循环中,您可以多次获得相同的值。您应该保留一个 Random 实例并在同一实例上继续使用 Next

    //Function to get random number
    private static readonly Random getrandom = new Random();
    
    public static int GetRandomNumber(int min, int max)
    {
        lock(getrandom) // synchronize
        {
            return getrandom.Next(min, max);
        }
    }
    

    【讨论】:

    • 这不是@Guffa 6 个月前在回答中所说的吗? “如果您创建新实例的时间太近,它们将产生相同系列的随机数”
    • @Chris- 你说的没错。在此,我提供了它的实现。我认为这是一个很好的方法。效果更好。
    • 这是一个同步代码的实现,以便从 seval 线程中使用。这对于多线程应用程序来说很好,但对于单线程应用程序来说是浪费时间。
    • @SeanWorle:首先,我使用 Guffa 的方法进行了尝试。然后我尝试存储相同的Random 对象。在这两种情况下,我都得到了相同的随机数。使用 Pankaj 的方法并没有发生。也许这是随机,但我现在对此表示怀疑。我在同一秒内从不同线程查询随机数。
    • @testing:我同意 Pankaj 的方法是正确的。我要说的是可以简化成这样://获取随机数的函数 private static readonly Random getrandom = new Random(); public static int GetRandomNumber(int min, int max) { lock(getrandom ) { // 同步返回 getrandom.Next(min, max); } }
    【解决方案4】:

    注意new Random() 是在当前时间戳上播种的。

    如果您想只生成一个数字,您可以使用:

    new Random().Next( int.MinValue, int.MaxValue )

    有关更多信息,请查看Random 类,但请注意:

    但是,由于时钟的分辨率有限,因此使用无参数构造函数连续创建不同的 Random 对象会创建生成相同随机数序列的随机数生成器

    所以不要用这段代码来生成一系列随机数。

    【讨论】:

    • -1:默认种子是基于时间的;循环执行此操作,您将获得非常非随机的结果。您应该创建 一个 生成器并将其用于所有号码,而不是每次都使用单独的生成器。
    • 嘿,这不公平。问题是如何生成随机整数。没有提到循环或系列。
    • 好的,公平点。撤销。不过,我仍然认为不要在循环中使用new Random() 是很重要的一点。
    • 对于以后遇到这个的人来说,现在应该很明显了,但我只是指出来;答案已用这一点更新,不要在循环中使用它来处理多个值。
    【解决方案5】:
    Random r = new Random();
    int n = r.Next();
    

    【讨论】:

    • 这似乎是一个被低估的有价值的回应!
    • @nilon 好吧,这取决于 OP - 或像我这样的随机读者 - 想要什么,这可能是一个被高估的回应。在我的书中,int 介于 int.MinValue 和 int.MaxValue 之间,但这个调用(根据文档)从不发出负数。
    • @Eike 由于 OP 没有提供任何细节,我也觉得没有必要写一篇完整的博客文章。 ?‍♂️
    【解决方案6】:

    我想添加一个加密安全版本:

    RNGCryptoServiceProvider 类(MSDNdotnetperls

    它实现了 IDisposable。

    using (RNGCryptoServiceProvider rng = new RNGCryptoServiceProvider())
    {
       byte[] randomNumber = new byte[4];//4 for int32
       rng.GetBytes(randomNumber);
       int value = BitConverter.ToInt32(randomNumber, 0);
    }
    

    【讨论】:

      【解决方案7】:

      创建一个随机对象

      Random rand = new Random();
      

      并使用它

      int randomNumber = rand.Next(min, max);
      

      您不必每次需要随机数时都初始化new Random(),启动一个随机数,然后在循环或其他任何内容中根据需要多次使用它

      【讨论】:

      • new Random() 使用当前报价作为种子。当您在同一毫秒内实例化多个实例(而不是滴答声)时,您将获得相同的返回值。
      • 这很糟糕。 DateTime.Now.Millisecond(与 DateTime.Now.Ticks 不同)是一个介于 0 和 999 之间的数字。如果您为每个随机数创建一个新的,那么您将只有 1000 种可能性。
      • 24 个人在投票赞成这个答案时是怎么想的...?
      【解决方案8】:

      您可以在他为伪随机数构建的 MiscUtil 类库中使用 Jon Skeet 的 StaticRandom 方法。

      using MiscUtil;
      ...
      
      for (int i = 0; i < 100; 
          Console.WriteLine(StaticRandom.Next());
      

      【讨论】:

      • 我刚看了一下源代码,这个函数使用完全相同的随机数引擎,C#中“包含”的引擎,但确保相同的“种子”/“母对象” " 用于所有呼叫。 (很抱歉,我不知道 C# 术语。但我的意思是,这个函数不会产生比标准函数更好的随机数。)
      • 任何事物都不可能是“真正随机的”,因为它的存在总是包含一些限制因素或偏见。你在科学课上没听老师的话吗? ;-)
      • 比方说,在他看来,这是“真正随机的”
      【解决方案9】:

      我已经尝试了所有这些解决方案,不包括 COBOL 答案...大声笑

      这些解决方案都不够好。我需要快速 for int 循环中的随机数,即使在非常宽的范围内,我也会得到大量重复值。在适应了太久的随机结果之后,我决定最终一劳永逸地解决这个问题。

      一切都与种子有关。

      我通过解析 Guid 中的非数字来创建一个随机整数,然后我用它来实例化我的 Random 类。

      public int GenerateRandom(int min, int max)
      {
          var seed = Convert.ToInt32(Regex.Match(Guid.NewGuid().ToString(), @"\d+").Value);
          return new Random(seed).Next(min, max);
      }
      

      更新:如果您将 Random 类实例化一次,则不需要播种。所以最好创建一个静态类并调用它的方法。

      public static class IntUtil
      {
         private static Random random;
      
         private static void Init()
         {
            if (random == null) random = new Random();
         }
      
         public static int Random(int min, int max)
         {
            Init();
            return random.Next(min, max);
         }
      }
      

      然后你可以像这样使用静态类..

      for(var i = 0; i < 1000; i++)
      {
         int randomNumber = IntUtil.Random(1,100);
         Console.WriteLine(randomNumber); 
      }
      

      我承认我更喜欢这种方法。

      【讨论】:

      • Guid 不是随机的,它不是一个好种子。 GUID 不保证随机性,它保证唯一性。 stackoverflow.com/questions/2621563/…
      • Guid 是个好种子。我只使用 Guid 中的数字。自己试试这个方法。把它放在一个很长的for循环中,自己看看结果。
      • 嗯,再三考虑.. 根本不需要种子。更新答案
      • 更新的重点。我什至没有想过让它成为一个静态字段,这种方式效果更好,更干净。
      • 这个答案有一些问题。首先,GUID 不是一个很好的种子源——仅仅因为它看起来是随机的并不意味着它是。它可能足以满足您的个人需求。其次, Random 类不是线程安全的。您需要为每个线程实例化一次。
      【解决方案10】:

      内置Random类(System.Random)生成的数字生成伪随机数。

      如果你想要真正的随机数,我们能得到的最接近的是“安全伪随机生成器”,它可以通过使用 C# 中的 Cryptographic 类来生成,例如 RNGCryptoServiceProvider

      即便如此,如果您仍然需要 true 随机数,您将需要使用外部源(例如考虑放射性衰变的设备)作为随机数生成器的种子。因为,根据定义,纯算法生成的任何数字都不能是真正随机的。

      【讨论】:

        【解决方案11】:

        来自here的修改答案。

        如果您可以访问与 Intel Secure Key 兼容的 CPU,则可以使用以下库生成真正的随机数和字符串:https://github.com/JebteK/RdRandhttps://www.rdrand.com/

        只需从here 下载最新版本,包括 Jebtek.RdRand 并为其添加 using 语句。然后,您需要做的就是:

        // Check to see if this is a compatible CPU
        bool isAvailable = RdRandom.GeneratorAvailable();
        
        // Generate 10 random characters
        string key       = RdRandom.GenerateKey(10);
        
         // Generate 64 random characters, useful for API keys 
        string apiKey    = RdRandom.GenerateAPIKey();
        
        // Generate an array of 10 random bytes
        byte[] b         = RdRandom.GenerateBytes(10);
        
        // Generate a random unsigned int
        uint i           = RdRandom.GenerateUnsignedInt();
        

        如果您没有兼容的 CPU 来执行代码,只需使用 rdrand.com 上的 RESTful 服务即可。使用您的项目中包含的 RdRandom 包装器库,您只需执行此操作(注册时您将获得 1000 次免费通话):

        string ret = Randomizer.GenerateKey(<length>, "<key>");
        uint ret   = Randomizer.GenerateUInt("<key>");
        byte[] ret = Randomizer.GenerateBytes(<length>, "<key>");
        

        【讨论】:

          【解决方案12】:

          仅供参考。

          如果您使用的是 .NET Core,则多个 Random 实例不会像以前那样危险。我知道这个问题是从 2010 年开始的,但是由于这个问题很老但有一些吸引力,我认为记录更改是一件好事。

          你可以参考我之前提出的这个问题:

          Did Microsoft change Random default seed?

          基本上,他们已将默认种子从 Environment.TickCount 更改为 Guid.NewGuid().GetHashCode(),因此如果您创建 2 个 Random 实例,它将不会显示相同的数字。

          您可以在此处查看 .NET Framework/.NET Core (2.0.0+) 的文件差异:https://github.com/dotnet/coreclr/pull/2192/commits/9f6a0b675e5ac0065a268554de49162c539ff66d

          它不如 RNGCryptoServiceProvider 安全,但至少不会给你带来奇怪的结果。

          【讨论】:

          • 这已经过时了。使用 Guids 遭到了相当大的反对。代码现在是Interop.GetRandomBytes((byte*)&amp;result, sizeof(int));
          【解决方案13】:

          这是我使用的类。类似于RandomNumber.GenerateRandom(1, 666)

          internal static class RandomNumber
          {
              private static Random r = new Random();
              private static object l = new object();
              private static Random globalRandom = new Random();
              [ThreadStatic]
              private static Random localRandom;
              public static int GenerateNewRandom(int min, int max)
              {
                  return new Random().Next(min, max);
              }
              public static int GenerateLockedRandom(int min, int max)
              {
                  int result;
                  lock (RandomNumber.l)
                  {
                      result = RandomNumber.r.Next(min, max);
                  }
                  return result;
              }
              public static int GenerateRandom(int min, int max)
              {
                  Random random = RandomNumber.localRandom;
                  if (random == null)
                  {
                      int seed;
                      lock (RandomNumber.globalRandom)
                      {
                          seed = RandomNumber.globalRandom.Next();
                      }
                      random = (RandomNumber.localRandom = new Random(seed));
                  }
                  return random.Next(min, max);
              }
          }
          

          【讨论】:

          • 你的 GenerateRandom 类永远不会返回数字 666,只会返回 665。这是对 Random.Next 最大值的常见误解(特征)。
          【解决方案14】:

          虽然没关系:

          Random random = new Random();
          int randomNumber = random.Next()
          

          您大部分时间都希望控制限制(最小和最大数量)。所以你需要指定随机数的开始和结束位置。

          Next() 方法接受两个参数,最小值和最大值。

          所以如果我希望我的随机数介于 5 到 15 之间,我会这样做

          int randomNumber = random.Next(5, 16)
          

          【讨论】:

            【解决方案15】:

            我想演示每次使用新的随机生成器时会发生什么。假设您有两个方法或两个类,每个都需要一个随机数。你天真地把它们编码成这样:

            public class A
            {
                public A()
                {
                    var rnd=new Random();
                    ID=rnd.Next();
                }
                public int ID { get; private set; }
            }
            public class B
            {
                public B()
                {
                    var rnd=new Random();
                    ID=rnd.Next();
                }
                public int ID { get; private set; }
            }
            

            你认为你会得到两个不同的 ID 吗?

            class Program
            {
                static void Main(string[] args)
                {
                    A a=new A();
                    B b=new B();
            
                    int ida=a.ID, idb=b.ID;
                    // ida = 1452879101
                    // idb = 1452879101
                }
            }
            

            解决方案是始终使用单个静态随机生成器。像这样:

            public static class Utils
            {
                public static readonly Random random=new Random();
            }
            
            public class A
            {
                public A()
                {
                    ID=Utils.random.Next();
                }
                public int ID { get; private set; }
            }
            public class B
            {
                public B()
                {
                    ID=Utils.random.Next();
                }
                public int ID { get; private set; }
            }
            

            【讨论】:

            • 那你如何安全地选择种子?
            • 好吧,首先,如果您的对象是相隔 10 毫秒创建的,则生成的随机数与默认种子不同。其次,您可以混合任何随机的环境或过程数据来获得种子。然后是您是否想要一个很可能开始重复自身的长数字序列,或者即使两个流最终相同的多个流的权衡。如果您担心安全问题,无论如何,RNGCryptoServiceProvider 是一个更好的电话。
            • 如果有一个带有小型 α 粒子放射源的随机化芯片和一个探测器(烟雾探测器的工作原理),以便根据放射性衰变(非常随机)随机化数字,那将是一件很酷的事情。
            【解决方案16】:

            如其他答案中所述,一种良好的安全方法是使用安全密码生成器。这里的所有示例都显示了RNGCryptoServiceProvider 的用法,与我建议的解决方案相比,它编写的代码很长。

            使用写在密码学 API 之上的RandomNumberGenerator。它与RNGCryptoServiceProvider 一样安全,并且具有相同的随机性。

            // Gives a random number for the integer range.
            // You can simply update the parameters as your needs.
            RandomNumberGenerator.GetInt32(int.MinValue, int.MaxValue);
            

            【讨论】:

            • 从 .NET 6 开始,RNGCryptoServiceProvider 已标记为 [Obsolete()],建议改为使用 RandomNumberGenerator
            【解决方案17】:

            计算机通过确定性过程计算出的数字,根据定义,不能是随机的。

            如果你想要一个真正的随机数,随机性来自大气噪声或放射性衰变。

            您可以尝试例如 RANDOM.ORG(它会降低性能)

            【讨论】:

              【解决方案18】:
              Random rand = new Random();
              int name = rand.Next()
              

              把你想要的任何值放在第二个括号里 确保您已通过编写 prop 和双制表符来生成代码来设置名称

              【讨论】:

              • 为什么要prop和双标签?你是说没有那个键盘快捷键,它是属性的简写,你的代码就不能工作吗?
              【解决方案19】:

              对于强随机种子,我总是使用 CryptoRNG 而不是 Time。

              using System;
              using System.Security.Cryptography;
              
              public class Program
              {
                  public static void Main()
                  {
                      var random = new Random(GetSeed());
                      Console.WriteLine(random.Next());
                  }
              
                  public static int GetSeed() 
                  {
                      using (var rng = new RNGCryptoServiceProvider())
                      {
                          var intBytes = new byte[4];
                          rng.GetBytes(intBytes);
                          return BitConverter.ToInt32(intBytes, 0);
                      }
                  }
              }
              

              【讨论】:

              • 您正在使用一个随机数生成器来获取另一个随机数生成器的种子?如果您需要“强”种子,那么您是否也想要(加密)强数字输出?为什么现在不使用RNGCryptoServiceProvider 处理所有内容?
              【解决方案20】:
              Random random = new Random ();
              int randomNumber = random.Next (lowerBound,upperBound);
              

              【讨论】:

              • 虽然这段代码可以回答问题,但最好解释一下如何解决问题,并提供代码作为示例或参考。仅代码的答案可能会令人困惑且缺乏上下文。
              【解决方案21】:

              如果您希望 CSRNG 生成介于最小值和最大值之间的随机数,那么这是给您的。它将使用安全随机种子初始化 Random 类。

                  class SecureRandom : Random
                  {
                      public static byte[] GetBytes(ulong length)
                      {
                          RNGCryptoServiceProvider RNG = new RNGCryptoServiceProvider();
                          byte[] bytes = new byte[length];
                          RNG.GetBytes(bytes);
                          RNG.Dispose();
                          return bytes;
                      }
                      public SecureRandom() : base(BitConverter.ToInt32(GetBytes(4), 0))
                      {
              
                      }
                      public int GetRandomInt(int min, int max)
                      {
                          int treashold = max - min;
                          if(treashold != Math.Abs(treashold))
                          {
                              throw new ArithmeticException("The minimum value can't exceed the maximum value!");
                          }
                          if (treashold == 0)
                          {
                              throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
                          }
                          return min + (Next() % treashold);
                      }
                      public static int GetRandomIntStatic(int min, int max)
                      {
                          int treashold = max - min;
                          if (treashold != Math.Abs(treashold))
                          {
                              throw new ArithmeticException("The minimum value can't exceed the maximum value!");
                          }
                          if(treashold == 0)
                          {
                              throw new ArithmeticException("The minimum value can't be the same as the maximum value!");
                          }
                          return min + (BitConverter.ToInt32(GetBytes(4), 0) % treashold);
                      }
                  }
              

              【讨论】:

                【解决方案22】:

                抱歉,OP 确实需要一个随机的 int 值,但是如果您想要一个随机的 BigInteger 值,为了简单的分享知识,您可以使用以下语句:

                BigInteger randomVal = BigInteger.Abs(BigInteger.Parse(Guid.NewGuid().ToString().Replace("-",""), NumberStyles.AllowHexSpecifier));
                

                【讨论】:

                • 我认为您最好使用byte[] bytes = new byte[byteCount]; random.NextBytes(bytes); BigInteger value = new BigInteger(bytes); 或重复调用Random.Next((int) '0', ((int) '9') + 1) 来构建随机数字的string 并对其进行解析。 Guid 的这种(ab)用法是非正统的,并且几乎可以保证返回天文数字(所以不是真正的“随机”)。此外,the documentation 建议“......应用程序NewGuid 方法用于加密目的。”
                【解决方案23】:

                有许多实用功能或服务可以更好地缓存,就像 System.Random 应该的那样,因此它适合通用实现:

                static public class CachedService<T> where T : new() {
                    static public T Get { get; } = new T();
                }
                

                用于随机(或类似):

                CachedService<System.Random>.Get.Next(999);
                

                【讨论】:

                  【解决方案24】:

                  在 C# 中获取随机数

                  Random rand = new Random();
                  int i = rand.Next();
                  

                  如果你想生成随机数,你可以使用一些随机数生成器,比如

                  【讨论】:

                    【解决方案25】:

                    我假设您想要一个如下所示的均匀分布的随机数生成器。大多数编程语言(包括 C# 和 C++)中的随机数在使用它们之前都没有正确洗牌。这意味着您将一遍又一遍地获得相同的数字,这并不是真正随机的。为避免一遍又一遍地绘制相同的数字,您需要一个种子。通常,对于这个任务来说,时间滴答是可以的。请记住,如果您每次都使用相同的种子,您将一遍又一遍地获得相同的数字。因此,请尝试始终使用不同的种子。时间是种子的好来源,因为它们总是在变化。

                    int GetRandomNumber(int min, int max)
                    {
                        Random rand = new Random((int)DateTime.Now.Ticks);
                        return rand.Next(min, max);
                    }
                    

                    如果您正在寻找正态分布的随机数生成器,您可以使用 Box-Muller 变换。检查 yoyoyoyosef 在随机高斯变量问题中的答案。由于您需要整数,因此您必须在最后将双精度值转换为整数。

                    Random rand = new Random(); //reuse this if you are generating many
                    double u1 = 1.0-rand.NextDouble(); //uniform(0,1] random doubles
                    double u2 = 1.0-rand.NextDouble();
                    double randStdNormal = Math.Sqrt(-2.0 * Math.Log(u1)) *
                             Math.Sin(2.0 * Math.PI * u2); //random normal(0,1)
                    double randNormal =
                             mean + stdDev * randStdNormal; //random normal(mean,stdDev^2)
                    

                    Random Gaussian Variables

                    【讨论】:

                      【解决方案26】:
                      Random r=new Random();
                      int Numbers=r.next(min value, max value);
                      

                      【讨论】:

                      • 该方法名为Next,而不是next,因此无法编译。此外,上限参数是exclusive,因此r.Next(minValue, maxValue); 将返回的最大数字实际上是maxValue - 1Numbers 对于存储单个数字的变量来说也是一个坏名字。最后,也是最重要的一点,Random 类的这种基本用法已被许多其他答案所涵盖。
                      【解决方案27】:

                      为什么不使用int randomNumber = Random.Range(start_range, end_range)

                      【讨论】:

                      • 其实 int randomNumber = Random.Range(start_range, end_range + 1)
                      • Random.Range() 是否存在?我在 MSDN 文档中找不到它。
                      • 这似乎是specific to Unity。如果是这样,说明并解释how it compares to System.Random会很有帮助。
                      【解决方案28】:

                      重复使用一个 Random 实例

                      // Somewhat better code...
                      Random rng = new Random();
                      for (int i = 0; i < 100; i++)
                      {
                          Console.WriteLine(GenerateDigit(rng));
                      }
                      ...
                      static int GenerateDigit(Random rng)
                      {
                          // Assume there'd be more logic here really
                          return rng.Next(10);
                      }
                      

                      本文着眼于为什么随机性会导致如此多的问题,以及如何解决这些问题。 http://csharpindepth.com/Articles/Chapter12/Random.aspx

                      【讨论】:

                      • Random 不是线程安全类。如果您创建单个实例,则应通过锁定机制限制对其的访问。
                      【解决方案29】:

                      尝试这些简单的步骤来创建随机数:

                      创建函数:

                      private int randomnumber(int min, int max)
                      {
                          Random rnum = new Random();
                          return rnum.Next(min, max);
                      }
                      

                      在你想使用随机数的地方使用上面的函数。假设您想在文本框中使用它。

                      textBox1.Text = randomnumber(0, 999).ToString();
                      

                      0 是最小值,999 是最大值。您可以将值更改为您想要的任何值。

                      【讨论】:

                      • 这将在多次调用时返回相同的数字,因为它使用系统时间作为种子...
                      • randomnumber(0, 999) 永远不会返回 999。最大值不包括在内。这是 Random.Next 最大值的常见误解(特征)。
                      【解决方案30】:

                      我总是有一些方法可以生成有助于各种目的的随机数。我希望这对你也有帮助:

                      public class RandomGenerator  
                      {  
                          public int RandomNumber(int min, int max)  
                          {  
                              var random = new Random();  
                              return random.Next(min, max);  
                          }  
                      
                          public string RandomString(int size, bool lowerCase)  
                          {  
                              var builder = new StringBuilder();  
                              var random  = new Random();  
                              char ch;  
                      
                              for (int i = 0; i < size; i++)  
                              {  
                                  ch = Convert.ToChar(Convert.ToInt32(Math.Floor(26 * random.NextDouble() + 65)));  
                                  builder.Append(ch);  
                              }  
                      
                              if (lowerCase)  
                                  return builder.ToString().ToLower();  
                              return builder.ToString();  
                          }  
                      }
                      

                      【讨论】:

                        猜你喜欢
                        • 1970-01-01
                        • 2018-05-15
                        • 2018-10-09
                        • 2014-08-22
                        • 2015-08-05
                        • 1970-01-01
                        • 1970-01-01
                        • 2010-10-23
                        相关资源
                        最近更新 更多