表示伪随机数生成器,这是一种能够产生满足某些随机性统计要求的数字序列的设备。
若要浏览此类型的.NET Framework 源代码,请参阅 Reference Source。
命名空间: System
程序集: mscorlib(位于 mscorlib.dll)
名称 | 说明 | |
---|---|---|
Random() |
新实例初始化 Random 类,使用依赖于时间的默认种子值。 |
|
Random(Int32) |
新实例初始化 Random 类,使用指定的种子值。 |
名称 | 说明 | |
---|---|---|
Equals(Object) |
确定指定的对象是否等于当前对象。(继承自 Object。) |
|
Finalize() |
在垃圾回收将某一对象回收前允许该对象尝试释放资源并执行其他清理操作。(继承自 Object。) |
|
GetHashCode() |
作为默认哈希函数。(继承自 Object。) |
|
GetType() | ||
MemberwiseClone() | ||
Next() |
返回一个非负随机整数。 |
|
Next(Int32) |
返回一个小于所指定最大值的非负随机整数。 |
|
Next(Int32, Int32) |
返回在指定范围内的任意整数。 |
|
NextBytes(Byte[]) |
用随机数填充指定字节数组的元素。 |
|
NextDouble() |
返回一个大于或等于 0.0 且小于 1.0 的随机浮点数。 |
|
Sample() |
返回一个介于 0.0 和 1.0 之间的随机浮点数。 |
|
ToString() |
返回表示当前对象的字符串。(继承自 Object。) |
说明 |
---|
若要查看此类型的.NET Framework 源代码,请参阅 Reference Source。 您可以浏览源代码、 下载脱机查看参考资料和调试; 在逐句通过源 (包括修补程序和更新)see instructions. |
伪随机数字从一组有限的数字选择以相同的概率。 因为数学算法可用于选择它们,但它们是充分随机实用的角度而言,所选的数字不完全随机的。 当前实现 Random 类根据 Donald E.Knuth 删减随机数生成器算法的修改版本。 有关详细信息,请参阅 D.e。 Knuth。 计算机编程,卷 2 的艺术︰ Seminumerical 算法。 Addison-wesley,Reading,MA,第三个版本,1997年。
若要生成加密性极安全的随机数字,如一个适合于创建随机密码,使用 RNGCryptoServiceProvider 类或从派生类 System.Security.Cryptography.RandomNumberGenerator。
在本主题中:
实例化的随机数字生成器
避免多个实例化
System.Random 类和线程安全
生成不同类型的随机数字
替换您自己的算法
如何使用到 System.Random…
检索相同的随机值序列
检索唯一的随机值序列
检索指定范围内的整数
检索具有指定位数的数字的整数
检索指定范围中的浮点值
生成随机的布尔值
生成随机的 64 位整数
检索指定范围中的字节
随机从数组或集合检索某个元素
检索的唯一元素从数组或集合
通过提供一个种子值 (起始值的伪随机数字生成算法) 的随机数字生成器实例化为 Random 类构造函数。 您可以显式或隐式提供种子值︰
如果同一个种子用于单独 Random 对象,则它们将生成相同的一系列随机数字。 这可以是用于创建测试套件,用于处理随机值,或者用于重播从随机数字派生其数据的游戏。 但请注意, Random 不同版本的.NET Framework 下运行的进程中的对象可能会返回不同的随机数字的序列,即使它们使用相同的种子值实例化。
若要生成的随机数的不同序列,您可以种子值依赖于时间,从而产生不同的系列的每个新实例 Random。 参数化 Random(Int32) 构造函数可以采用 Int32 值根据计时周期数以当前时间,而无参数 Random() 构造函数使用系统时钟生成其种子值。 不过,由于时钟具有有限的解决方法,使用无参数构造函数来创建不同 Random 中连续的对象创建生成的随机数的相同序列生成器。 下面的示例阐释了两个 Random 连续实例化的对象生成相同的一系列随机数字。 在大多数 Windows 系统, Random 在另一个 15 毫秒内创建的对象可能会遇到的相同种子值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 |
using System; public class Class1 { public static void Main() { byte[] bytes1 = new byte[100]; byte[] bytes2 = new byte[100]; Random rnd1 = new Random(); Random rnd2 = new Random(); rnd1.NextBytes(bytes1); rnd2.NextBytes(bytes2); Console.WriteLine("First Series:"); for (int ctr = bytes1.GetLowerBound(0); ctr <= bytes1.GetUpperBound(0); ctr++) { Console.Write("{0, 5}", bytes1[ctr]); if ((ctr + 1) % 10 == 0) Console.WriteLine(); } Console.WriteLine(); Console.WriteLine("Second Series:"); for (int ctr = bytes2.GetLowerBound(0); ctr <= bytes2.GetUpperBound(0); ctr++) { Console.Write("{0, 5}", bytes2[ctr]); if ((ctr + 1) % 10 == 0) Console.WriteLine(); } } } // The example displays output like the following: // First Series: // 97 129 149 54 22 208 120 105 68 177 // 113 214 30 172 74 218 116 230 89 18 // 12 112 130 105 116 180 190 200 187 120 // 7 198 233 158 58 51 50 170 98 23 // 21 1 113 74 146 245 34 255 96 24 // 232 255 23 9 167 240 255 44 194 98 // 18 175 173 204 169 171 236 127 114 23 // 167 202 132 65 253 11 254 56 214 127 // 145 191 104 163 143 7 174 224 247 73 // 52 6 231 255 5 101 83 165 160 231 // // Second Series: // 97 129 149 54 22 208 120 105 68 177 // 113 214 30 172 74 218 116 230 89 18 // 12 112 130 105 116 180 190 200 187 120 // 7 198 233 158 58 51 50 170 98 23 // 21 1 113 74 146 245 34 255 96 24 // 232 255 23 9 167 240 255 44 194 98 // 18 175 173 204 169 171 236 127 114 23 // 167 202 132 65 253 11 254 56 214 127 // 145 191 104 163 143 7 174 224 247 73 // 52 6 231 255 5 101 83 165 160 231 |
若要避免此问题,创建一个 Random 对象而不是多个对象。
初始化两个随机数生成器的紧凑循环中或在短期内创建两个随机数生成器可能会产生相同的随机数字序列。 在大多数情况下,这不是开发人员的意图,会导致性能问题,因为实例化和初始化随机数生成器是一个代价相对较大的过程。
同时以提高性能并避免无意中创建单独的随机数生成器生成相同的数字序列,我们建议您创建一个 Random 对象来生成段时间后,而不是创建新的多个随机数 Random 对象生成一个随机数。
但是, Random 类不是线程安全。 如果调用 Random 方法从多个线程,请按照下一节中讨论的指导原则。
而不是实例化单个 Random 对象时,我们建议您创建一个 Random 实例,以生成应用程序所需的所有随机数字。 但是, Random 对象不是线程安全。 如果您的应用程序调用 Random 从多个线程的方法,您必须使用同步对象来确保只有一个线程可以访问一次的随机数字生成器。 如果您不确保 Random 以线程安全的方式访问对象时,对返回随机数字的方法的调用将返回 0。
下面的示例使用 C# 锁定语句 和 Visual Basic SyncLock 语句 以确保单个随机数生成器的 11 个线程访问以线程安全的方式。 每个线程生成 2 百万个随机数字、 对生成的随机数字的数量进行计数和计算其总和,并执行完后,然后更新所有线程的合计。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 |
using System; using System.Threading; public class Example { [ThreadStatic] static double previous = 0.0; [ThreadStatic] static int perThreadCtr = 0; [ThreadStatic] static double perThreadTotal = 0.0; static CancellationTokenSource source; static CountdownEvent countdown; static Object randLock, numericLock; static Random rand; double totalValue = 0.0; int totalCount = 0; public Example() { rand = new Random(); randLock = new Object(); numericLock = new Object(); countdown = new CountdownEvent(1); source = new CancellationTokenSource(); } public static void Main() { Example ex = new Example(); Thread.CurrentThread.Name = "Main"; ex.Execute(); } private void Execute() { CancellationToken token = source.Token; for (int threads = 1; threads <= 10; threads++) { Thread newThread = new Thread(this.GetRandomNumbers); newThread.Name = threads.ToString(); newThread.Start(token); } this.GetRandomNumbers(token); countdown.Signal(); // Make sure all threads have finished. countdown.Wait(); source.Dispose(); Console.WriteLine("\nTotal random numbers generated: {0:N0}", totalCount); Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue); Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount); } private void GetRandomNumbers(Object o) { CancellationToken token = (CancellationToken) o; double result = 0.0; countdown.AddCount(1); try { for (int ctr = 0; ctr < 2000000; ctr++) { // Make sure there's no corruption of Random. token.ThrowIfCancellationRequested(); lock (randLock) { result = rand.NextDouble(); } // Check for corruption of Random instance. if ((result == previous) && result == 0) { source.Cancel(); } else { previous = result; } perThreadCtr++; perThreadTotal += result; } Console.WriteLine("Thread {0} finished execution.", Thread.CurrentThread.Name); Console.WriteLine("Random numbers generated: {0:N0}", perThreadCtr); Console.WriteLine("Sum of random numbers: {0:N2}", perThreadTotal); Console.WriteLine("Random number mean: {0:N4}\n", perThreadTotal/perThreadCtr); // Update overall totals. lock (numericLock) { totalCount += perThreadCtr; totalValue += perThreadTotal; } } catch (OperationCanceledException e) { Console.WriteLine("Corruption in Thread {1}", e.GetType().Name, Thread.CurrentThread.Name); } finally { countdown.Signal(); } } } // The example displays output like the following: // Thread 6 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,491.05 // Random number mean: 0.5002 // // Thread 10 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,329.64 // Random number mean: 0.4997 // // Thread 4 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,166.89 // Random number mean: 0.5001 // // Thread 8 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,628.37 // Random number mean: 0.4998 // // Thread Main finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,920.89 // Random number mean: 0.5000 // // Thread 3 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,370.45 // Random number mean: 0.4997 // // Thread 7 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,330.92 // Random number mean: 0.4997 // // Thread 9 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,172.79 // Random number mean: 0.5001 // // Thread 5 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,079.43 // Random number mean: 0.5000 // // Thread 1 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,817.91 // Random number mean: 0.4999 // // Thread 2 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,930.63 // Random number mean: 0.5000 // // // Total random numbers generated: 22,000,000 // Total sum of all random numbers: 10,998,238.98 // Random number mean: 0.4999 |
该示例通过以下方式将确保线程安全︰
下面的示例等同于第一,只不过它使用 Task 对象和 lambda 表达式而不是 Thread 对象。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 |
using System; using System.Collections.Generic; using System.Threading; using System.Threading.Tasks; public class Example { static Object randLock, numericLock; static Random rand; static CancellationTokenSource source; double totalValue = 0.0; int totalCount = 0; public Example() { rand = new Random(); randLock = new Object(); numericLock = new Object(); source = new CancellationTokenSource(); } public static void Main() { Example ex = new Example(); Thread.CurrentThread.Name = "Main"; ex.Execute(); } private void Execute() { List<Task> tasks = new List<Task>(); for (int ctr = 0; ctr <= 10; ctr++) { CancellationToken token = source.Token; int taskNo = ctr; tasks.Add(Task.Run( () => { double previous = 0.0; int taskCtr = 0; double taskTotal = 0.0; double result = 0.0; for (int n = 0; n < 2000000; n++) { // Make sure there's no corruption of Random. token.ThrowIfCancellationRequested(); lock (randLock) { result = rand.NextDouble(); } // Check for corruption of Random instance. if ((result == previous) && result == 0) { source.Cancel(); } else { previous = result; } taskCtr++; taskTotal += result; } // Show result. Console.WriteLine("Task {0} finished execution.", taskNo); Console.WriteLine("Random numbers generated: {0:N0}", taskCtr); Console.WriteLine("Sum of random numbers: {0:N2}", taskTotal); Console.WriteLine("Random number mean: {0:N4}\n", taskTotal/taskCtr); // Update overall totals. lock (numericLock) { totalCount += taskCtr; totalValue += taskTotal; } }, token)); } try { Task.WaitAll(tasks.ToArray()); Console.WriteLine("\nTotal random numbers generated: {0:N0}", totalCount); Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue); Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount); } catch (AggregateException e) { foreach (Exception inner in e.InnerExceptions) { TaskCanceledException canc = inner as TaskCanceledException; if (canc != null) Console.WriteLine("Task #{0} cancelled.", canc.Task.Id); else Console.WriteLine("Exception: {0}", inner.GetType().Name); } } finally { source.Dispose(); } } } // The example displays output like the following: // Task 1 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,502.47 // Random number mean: 0.5003 // // Task 0 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,445.63 // Random number mean: 0.5002 // // Task 2 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,556.04 // Random number mean: 0.5003 // // Task 3 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,178.87 // Random number mean: 0.5001 // // Task 4 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,819.17 // Random number mean: 0.4999 // // Task 5 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,190.58 // Random number mean: 0.5001 // // Task 6 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,720.21 // Random number mean: 0.4999 // // Task 7 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,000.96 // Random number mean: 0.4995 // // Task 8 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,499.33 // Random number mean: 0.4997 // // Task 9 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 1,000,193.25 // Random number mean: 0.5001 // // Task 10 finished execution. // Random numbers generated: 2,000,000 // Sum of random numbers: 999,960.82 // Random number mean: 0.5000 // // // Total random numbers generated: 22,000,000 // Total sum of all random numbers: 11,000,067.33 // Random number mean: 0.5000 |
在以下方面不同的第一个示例︰
随机数字生成器提供了方法,您可以生成以下类型的随机数字︰
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System; public class Example { public static void Main() { Random rnd = new Random(); Byte[] bytes = new Byte[20]; rnd.NextBytes(bytes); for (int ctr = 1; ctr <= bytes.Length; ctr++) { Console.Write("{0,3} ", bytes[ctr - 1]); if (ctr % 10 == 0) Console.WriteLine(); } } } // The example displays output like the following: // 141 48 189 66 134 212 211 71 161 56 // 181 166 220 133 9 252 222 57 62 62 |
下面的示例调用 Next(Int32, Int32) 方法来生成 10 个随机数字介于-10 和 10 之间。 请注意,该方法的第二个参数指定的由该方法返回的随机值的范围的上限。 换而言之,该方法可返回一个的最大整数少于此值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
using System; public class Example { public static void Main() { Random rnd = new Random(); for (int ctr = 0; ctr < 10; ctr++) { Console.Write("{0,3} ", rnd.Next(-10, 11)); } } } // The example displays output like the following: // 2 9 -3 2 4 -7 -3 -8 -8 5 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 |
using System; public class Example { public static void Main() { Random rnd = new Random(); for (int ctr = 0; ctr < 10; ctr++) { Console.Write("{0,-19:R} ", rnd.NextDouble()); if ((ctr + 1) % 3 == 0) Console.WriteLine(); } } } // The example displays output like the following: // 0.7911680553998649 0.0903414949264105 0.79776258291572455 // 0.615568345233597 0.652644504165577 0.84023809378977776 // 0.099662564741290441 0.91341467383942321 0.96018602045261581 // 0.74772306473354022 |
重要事项 |
---|
Next(Int32, Int32) 方法允许您指定返回的随机数的范围。 但是, maxValue 参数,指定的上限范围返回数字,该参数是独占的、 不含值。这意味着方法调用 Next(0, 100) 返回一个值,介于 0 和 99 之间并不介于 0 和 100 之间。 |
您还可以使用 Random 之类的任务生成的类 随机的布尔值, 、 生成 随机浮点值的范围以外的 0 到 1, 、 生成 64 位的随机整数, ,和 随机从数组或集合中检索的唯一元素。 有关这些和其他常见任务,请参阅 如何使用到 System.Random… 部分。
您可以通过继承实现您自己的随机数字生成器 Random 类并提供您随机数字生成算法。 若要提供您自己的算法,必须重写 Sample 方法,实现随机数字生成算法。 您还应该重写 Next(), ,Next(Int32, Int32), ,和 NextBytes 方法以确保它们调用被重写 Sample 方法。 您无需重写 Next(Int32) 和 NextDouble 方法。
有关示例,派生自 Random 类并修改其默认的伪随机数生成器,请参阅 Sample 引用页面。
以下各节讨论并提供了几种可能想要在您的应用程序中使用的随机数的示例代码。
有时您想要在软件测试方案和玩游戏生成相同的随机数字序列。 使用相同的随机数字序列进行测试,可检测到回归测试并确认 bug 已修复。 在游戏中使用相同的随机数字序列可以重播以前的游戏。
您可以通过提供到相同的种子值生成相同的随机数字序列 Random(Int32) 构造函数。 种子值为伪随机数字生成算法提供一个起始值。 下面的示例使用 100100 为任意种子值来实例化 Random 对象,显示 20 个随机浮点值,并且仍然存在的种子值。 然后还原的种子值、 实例化新的随机数字生成器,并显示相同的 20 随机浮点值。 请注意是否在不同版本的.NET Framework 上运行,则可能会产生不同的随机数字序列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 |
using System; using System.IO; public class Example { public static void Main() { int seed = 100100; ShowRandomNumbers(seed); Console.WriteLine(); PersistSeed(seed); DisplayNewRandomNumbers(); } private static void ShowRandomNumbers(int seed) { Random rnd = new Random(seed); for (int ctr = 0; ctr <= 20; ctr++) Console.WriteLine(rnd.NextDouble()); } private static void PersistSeed(int seed) { FileStream fs = new FileStream(@".\seed.dat", FileMode.Create); BinaryWriter bin = new BinaryWriter(fs); bin.Write(seed); bin.Close(); } private static void DisplayNewRandomNumbers() { FileStream fs = new FileStream(@".\seed.dat", FileMode.Open); BinaryReader bin = new BinaryReader(fs); int seed = bin.ReadInt32(); bin.Close(); Random rnd = new Random(seed); for (int ctr = 0; ctr <= 20; ctr++) Console.WriteLine(rnd.NextDouble()); } } // The example displays output like the following: // 0.500193602172748 // 0.0209461245783354 // 0.465869495396442 // 0.195512794514891 // 0.928583675496552 // 0.729333720509584 // 0.381455668891527 // 0.0508996467343064 // 0.019261200921266 // 0.258578445417145 // 0.0177532266908107 // 0.983277184415272 // 0.483650274334313 // 0.0219647376900375 // 0.165910115077118 // 0.572085966622497 // 0.805291457942357 // 0.927985211335116 // 0.4228545699375 // 0.523320379910674 // 0.157783938645285 // // 0.500193602172748 // 0.0209461245783354 // 0.465869495396442 // 0.195512794514891 // 0.928583675496552 // 0.729333720509584 // 0.381455668891527 // 0.0508996467343064 // 0.019261200921266 // 0.258578445417145 // 0.0177532266908107 // 0.983277184415272 // 0.483650274334313 // 0.0219647376900375 // 0.165910115077118 // 0.572085966622497 // 0.805291457942357 // 0.927985211335116 // 0.4228545699375 // 0.523320379910674 // 0.157783938645285 |
提供不同的种子值的实例 Random 类将导致每个随机数生成器来生成不同的值序列。 可以通过调用显式提供一个种子值 Random(Int32) 构造函数,或隐式调用 Random() 构造函数。 大多数开发人员调用无参数构造函数,使用系统时钟。 下面的示例使用这种方法来实例化两个 Random 实例。 每个实例显示 10 个随机整数的一系列。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 |
using System; using System.Threading; public class Example { public static void Main() { Console.WriteLine("Instantiating two random number generators..."); Random rnd1 = new Random(); Thread.Sleep(2000); Random rnd2 = new Random(); Console.WriteLine("\nThe first random number generator:"); for (int ctr = 1; ctr <= 10; ctr++) Console.WriteLine(" {0}", rnd1.Next()); Console.WriteLine("\nThe second random number generator:"); for (int ctr = 1; ctr <= 10; ctr++) Console.WriteLine(" {0}", rnd2.Next()); } } // The example displays output like the following: // Instantiating two random number generators... // // The first random number generator: // 643164361 // 1606571630 // 1725607587 // 2138048432 // 496874898 // 1969147632 // 2034533749 // 1840964542 // 412380298 // 47518930 // // The second random number generator: // 1251659083 // 1514185439 // 1465798544 // 517841554 // 1821920222 // 195154223 // 1538948391 // 1548375095 // 546062716 // 897797880 |
但是,由于其有限的解决方法,系统时钟不会检测少于大约 15 毫秒的时间差异。 因此,如果你的代码调用 Random() 要实例化两个重载 Random 中连续,您可能会无意中提供这些对象具有相同的种子值的对象。 若要查看此上一示例中,注释掉 Thread.Sleep 方法调用和编译和重新运行该示例。
若要防止这种情况发生,我们建议您实例化一个 Random 对象而不是多个会话。 但是,由于 Random 不是线程安全的如果您访问,则必须使用一些同步设备 Random 实例从多个线程; 有关详细信息,请参阅 随机的类和线程安全 本主题前面的。 或者,可以使用延迟机制,如 Sleep 方法使用在上一示例中,以确保实例化会相隔超过 15 毫秒。
可以通过调用来检索指定范围内的整数 Next(Int32, Int32) 方法,可以指定您想要返回的随机数生成器的数的上限和较低。 上限是独占的、 不含值。 也就是说,它不包含在由该方法返回的值的范围。 下面的示例使用此方法生成介于-10 和 10 之间的随机整数。 请注意,它指定 11 中,这是一个大于所需的值,该值的 maxValue 方法调用中的参数。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 |
using System; public class Example { public static void Main() { Random rnd = new Random(); for (int ctr = 1; ctr <= 15; ctr++) { Console.Write("{0,3} ", rnd.Next(-10, 11)); if(ctr % 5 == 0) Console.WriteLine(); } } } // The example displays output like the following: // -2 -5 -1 -2 10 // -3 6 -4 -8 3 // -7 10 5 -2 4 |
您可以调用 Next(Int32, Int32) 方法来检索具有指定位数的数字的数字。 例如,若要检索具有四位数字 (也就是说,范围为 1000年至 9999 的数字) 的数字,则调用 Next(Int32, Int32) 方法 minValue 当值为 1000年和 maxValue 值为 10000,如以下示例所示。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System; public class Example { public static void Main() { Random rnd = new Random(); for (int ctr = 1; ctr <= 50; ctr++) { Console.Write("{0,3} ", rnd.Next(1000, 10000)); if(ctr % 10 == 0) Console.WriteLine(); } } } // The example displays output like the following: // 9570 8979 5770 1606 3818 4735 8495 7196 7070 2313 // 5279 6577 5104 5734 4227 3373 7376 6007 8193 5540 // 7558 3934 3819 7392 1113 7191 6947 4963 9179 7907 // 3391 6667 7269 1838 7317 1981 5154 7377 3297 5320 // 9869 8694 2684 4949 2999 3019 2357 5211 9604 2593 |
NextDouble 方法返回随机浮点值,范围从 0 到小于 1。 但是,您通常需要在另一个范围中生成随机值。
如果最小值和最大所需值之间的间隔为 1 时,可以将所需的起始时间间隔和 0 之间的差异添加到返回的数字 NextDouble 方法。 下面的示例这样做是为了生成 10 个随机数字之间-1 和 0。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 |
using System; public class Example { public static void Main() { Random rnd = new Random(); for (int ctr = 1; ctr <= 10; ctr++) Console.WriteLine(rnd.NextDouble() - 1); } } // The example displays output like the following: // -0.930412760437658 // -0.164699016215605 // -0.9851692803135 // -0.43468508843085 // -0.177202483255976 // -0.776813320245972 // -0.0713201854710096 // -0.0912875561468711 // -0.540621722368813 // -0.232211863730201 |
生成随机浮点数其下限为 0,但上限大于 1 (或者,对于负数,其下限为小于-1,上限为 0),再乘以非零值绑定的随机数字。 下面的示例这样做是为了生成 2000 万个随机浮点数,范围从 0 到 Int64.MaxValue。 此外会在显示的方法生成的随机值的分布。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using System; public class Example { public static void Main() { const long ONE_TENTH = 922337203685477581; Random rnd = new Random(); double number; int[] count = new int[10]; // Generate 20 million integer values between. for (int ctr = 1; ctr <= 20000000; ctr++) { number = rnd.NextDouble() * Int64.MaxValue; // Categorize random numbers into 10 groups. count[(int) (number / ONE_TENTH)]++; } // Display breakdown by range. Console.WriteLine("{0,28} {1,32} {2,7}\n", "Range", "Count", "Pct."); for (int ctr = 0; ctr <= 9; ctr++) Console.WriteLine("{0,25:N0}-{1,25:N0} {2,8:N0} {3,7:P2}", ctr * ONE_TENTH, ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64.MaxValue, count[ctr], count[ctr]/20000000.0); } } // The example displays output like the following: // Range Count Pct. // // 0- 922,337,203,685,477,580 1,996,148 9.98 % // 922,337,203,685,477,581-1,844,674,407,370,955,161 2,000,293 10.00 % // 1,844,674,407,370,955,162-2,767,011,611,056,432,742 2,000,094 10.00 % // 2,767,011,611,056,432,743-3,689,348,814,741,910,323 2,000,159 10.00 % // 3,689,348,814,741,910,324-4,611,686,018,427,387,904 1,999,552 10.00 % // 4,611,686,018,427,387,905-5,534,023,222,112,865,485 1,998,248 9.99 % // 5,534,023,222,112,865,486-6,456,360,425,798,343,066 2,000,696 10.00 % // 6,456,360,425,798,343,067-7,378,697,629,483,820,647 2,001,637 10.01 % // 7,378,697,629,483,820,648-8,301,034,833,169,298,228 2,002,870 10.01 % // 8,301,034,833,169,298,229-9,223,372,036,854,775,807 2,000,303 10.00 % |
若要生成两个任意值之间的随机浮点数,喜欢 Next(Int32, Int32) 方法不为整数,则使用以下公式︰
1 |
Random.NextDouble() * (maxValue – minValue) + minValue |
下面的示例生成 100 万个随机数字,范围为从 10.0 为 11.0,并显示其分发。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System; public class Example { public static void Main() { Random rnd = new Random(); int lowerBound = 10; int upperBound = 11; int[] range = new int[10]; for (int ctr = 1; ctr <= 1000000; ctr++) { Double value = rnd.NextDouble() * (upperBound - lowerBound) + lowerBound; range[(int) Math.Truncate((value - lowerBound) * 10)]++; } for (int ctr = 0; ctr <= 9; ctr++) { Double lowerRange = 10 + ctr * .1; Console.WriteLine("{0:N1} to {1:N1}: {2,8:N0} ({3,7:P2})", lowerRange, lowerRange + .1, range[ctr], range[ctr] / 1000000.0); } } } // The example displays output like the following: // 10.0 to 10.1: 99,929 ( 9.99 %) // 10.1 to 10.2: 100,189 (10.02 %) // 10.2 to 10.3: 99,384 ( 9.94 %) // 10.3 to 10.4: 100,240 (10.02 %) // 10.4 to 10.5: 99,397 ( 9.94 %) // 10.5 to 10.6: 100,580 (10.06 %) // 10.6 to 10.7: 100,293 (10.03 %) // 10.7 to 10.8: 100,135 (10.01 %) // 10.8 to 10.9: 99,905 ( 9.99 %) // 10.9 to 11.0: 99,948 ( 9.99 %) |
Random 类没有提供生成的方法 Boolean 值。 但是,您可以定义您自己的类或方法来做到这一点。 下面的示例定义一个类, BooleanGenerator, ,具有单个方法 NextBoolean。 BooleanGenerator 类存储 Random 对象作为一个私有变量。 NextBoolean 方法调用 Random.Next(Int32, Int32) 方法并传递给 Convert.ToBoolean(Int32) 方法。 请注意,使用 2 作为参数来指定随机数的上限。 由于这是排他值,该方法调用将返回 0 或 1。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 |
using System; public class Example { public static void Main() { // Instantiate the Boolean generator. BooleanGenerator boolGen = new BooleanGenerator(); int totalTrue = 0, totalFalse = 0; // Generate 1,0000 random Booleans, and keep a running total. for (int ctr = 0; ctr < 1000000; ctr++) { bool value = boolGen.NextBoolean(); if (value) totalTrue++; else totalFalse++; } Console.WriteLine("Number of true values: {0,7:N0} ({1:P3})", totalTrue, ((double) totalTrue)/(totalTrue + totalFalse)); Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", totalFalse, ((double) totalFalse)/(totalTrue + totalFalse)); } } public class BooleanGenerator { Random rnd; public BooleanGenerator() { rnd = new Random(); } public bool NextBoolean() { return Convert.ToBoolean(rnd.Next(0, 2)); } } // The example displays output like the following: // Number of true values: 500,004 (50.000 %) // Number of false values: 499,996 (50.000 %) |
而不是创建一个单独的类生成随机 Boolean 值,则可能只需定义一种方法。 在这种情况下,但是, Random 对象应被定义为类级别变量,以避免实例化一个新 Random 中每个方法调用的实例。 在 Visual Basic 中,Random 实例可以定义为 静态 变量中 NextBoolean 方法。 下面的示例提供了一个实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 |
using System; public class Example { private static Random rnd = new Random(); public static void Main() { int totalTrue = 0, totalFalse = 0; // Generate 1,0000 random Booleans, and keep a running total. for (int ctr = 0; ctr < 1000000; ctr++) { bool value = NextBoolean(); if (value) totalTrue++; else totalFalse++; } Console.WriteLine("Number of true values: {0,7:N0} ({1:P3})", totalTrue, ((double) totalTrue)/(totalTrue + totalFalse)); Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", totalFalse, ((double) totalFalse)/(totalTrue + totalFalse)); } public static bool NextBoolean() { return Convert.ToBoolean(rnd.Next(0, 2)); } } // The example displays output like the following: // Number of true values: 499,777 (49.978 %) // Number of false values: 500,223 (50.022 %) |
重载 Next 方法返回 32 位整数。 但是,在某些情况下,您可能想要使用 64 位整数。 你可以按如下所示进行操作:
下面的示例使用该技术来生成 2000 万个随机长整数,并在 10 个相等组中对其进行分类。 然后通过计算从 0 到每个组中的数量计算分布的随机数字 Int64.MaxValue。 如示例输出所示,数字增加或减少均匀地分布在执行一个长整型的范围。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
using System; public class Example { public static void Main() { const long ONE_TENTH = 922337203685477581; Random rnd = new Random(); long number; int[] count = new int[10]; // Generate 20 million long integers. for (int ctr = 1; ctr <= 20000000; ctr++) { number = (long) (rnd.NextDouble() * Int64.MaxValue); // Categorize random numbers. count[(int) (number / ONE_TENTH)]++; } // Display breakdown by range. Console.WriteLine("{0,28} {1,32} {2,7}\n", "Range", "Count", "Pct."); for (int ctr = 0; ctr <= 9; ctr++) Console.WriteLine("{0,25:N0}-{1,25:N0} {2,8:N0} {3,7:P2}", ctr * ONE_TENTH, ctr < 9 ? ctr * ONE_TENTH + ONE_TENTH - 1 : Int64.MaxValue, count[ctr], count[ctr]/20000000.0); } } // The example displays output like the following: // Range Count Pct. // // 0- 922,337,203,685,477,580 1,996,148 9.98 % // 922,337,203,685,477,581-1,844,674,407,370,955,161 2,000,293 10.00 % // 1,844,674,407,370,955,162-2,767,011,611,056,432,742 2,000,094 10.00 % // 2,767,011,611,056,432,743-3,689,348,814,741,910,323 2,000,159 10.00 % // 3,689,348,814,741,910,324-4,611,686,018,427,387,904 1,999,552 10.00 % // 4,611,686,018,427,387,905-5,534,023,222,112,865,485 1,998,248 9.99 % // 5,534,023,222,112,865,486-6,456,360,425,798,343,066 2,000,696 10.00 % // 6,456,360,425,798,343,067-7,378,697,629,483,820,647 2,001,637 10.01 % // 7,378,697,629,483,820,648-8,301,034,833,169,298,228 2,002,870 10.01 % // 8,301,034,833,169,298,229-9,223,372,036,854,775,807 2,000,303 10.00 % |
使用位操作的替代技术不生成真正的随机数字。 此方法调用 Next() 来生成两个整数,左移一个由 32 位 Or 它们组合在一起。 此方法具有两个限制︰
重载 Next 方法允许您指定的随机数字,范围,但 NextBytes 方法却没有。 下面的示例实现 NextBytes 方法,可使您可以指定返回的字节范围。 它定义了 Random2 派生自的类 Random 并重载其 NextBytes 方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 |
using System; public class Example { public static void Main() { Random2 rnd = new Random2(); Byte[] bytes = new Byte[10000]; int[] total = new int[101]; rnd.NextBytes(bytes, 0, 101); // Calculate how many of each value we have. foreach (var value in bytes) total[value]++; // Display the results. for (int ctr = 0; ctr < total.Length; ctr++) { Console.Write("{0,3}: {1,-3} ", ctr, total[ctr]); if ((ctr + 1) % 5 == 0) Console.WriteLine(); } } } public class Random2 : Random { public Random2() : base() {} public Random2(int seed) : base(seed) {} public void NextBytes(byte[] bytes, byte minValue, byte maxValue) { for (int ctr = bytes.GetLowerBound(0); ctr <= bytes.GetUpperBound(0); ctr++) bytes[ctr] = (byte) Next(minValue, maxValue); } } // The example displays output like the following: // 0: 115 1: 119 2: 92 3: 98 4: 92 // 5: 102 6: 103 7: 84 8: 93 9: 116 // 10: 91 11: 98 12: 106 13: 91 14: 92 // 15: 101 16: 100 17: 96 18: 97 19: 100 // 20: 101 21: 106 22: 112 23: 82 24: 85 // 25: 102 26: 107 27: 98 28: 106 29: 102 // 30: 109 31: 108 32: 94 33: 101 34: 107 // 35: 101 36: 86 37: 100 38: 101 39: 102 // 40: 113 41: 95 42: 96 43: 89 44: 99 // 45: 81 46: 89 47: 105 48: 100 49: 85 // 50: 103 51: 103 52: 93 53: 89 54: 91 // 55: 97 56: 105 57: 97 58: 110 59: 86 // 60: 116 61: 94 62: 117 63: 98 64: 110 // 65: 93 66: 102 67: 100 68: 105 69: 83 // 70: 81 71: 97 72: 85 73: 70 74: 98 // 75: 100 76: 110 77: 114 78: 83 79: 90 // 80: 96 81: 112 82: 102 83: 102 84: 99 // 85: 81 86: 100 87: 93 88: 99 89: 118 // 90: 95 91: 124 92: 108 93: 96 94: 104 // 95: 106 96: 99 97: 99 98: 92 99: 99 // 100: 108 |
NextBytes(Byte[], Byte, Byte) 方法包装调用 Next(Int32, Int32) 方法,并指定的最小值和一个大于最大值 (在这种情况下,0 和 101),我们希望返回的字节数组中。 因为我们可以确保返回的整数值 Next 方法的范围内有 Byte 数据类型,我们可以安全地将它们强制转换 (在 C# 中) 或将它们 (在 Visual Basic 中) 从整数转换为字节。
随机数字经常充当要从数组或集合中检索值的索引。 若要检索随机索引值,可以调用 Next(Int32, Int32) 方法,并使用的下限数组的值作为其 minValue 参数和一个大于上限的数组的值作为其 maxValue 参数。 对于从零开始的数组,该属性等同于其 Length 属性,或一个返回的值大于 Array.GetUpperBound 方法。 下面的示例随机从一个城市数组检索在美国城市的名称。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
using System; public class Example { public static void Main() { String[] cities = { "Atlanta", "Boston", "Chicago", "Detroit", "Fort Wayne", "Greensboro", "Honolulu", "Indianapolis", "Jersey City", "Kansas City", "Los Angeles", "Milwaukee", "New York", "Omaha", "Philadelphia", "Raleigh", "San Francisco", "Tulsa", "Washington" }; Random rnd = new Random(); int index = rnd.Next(0, cities.Length); Console.WriteLine("Today's city of the day: {0}", cities[index]); } } // The example displays output like the following: // Today's city of the day: Honolulu |
随机数字生成器始终能够返回重复的值。 当的编号的范围变得更小或生成的值的数目越大,就会增加重复项的概率。 如果随机值必须是唯一的其他号码会生成来弥补重复项,从而越来越多地影响性能。
有多种方法来处理此情况。 一个常见的解决方案是创建一个包含随机浮点数的并行数组和数组或集合,其中包含要检索的值。 创建第一个数组,次用随机数填充第二个数组和 Array.Sort(Array, Array) 方法用于按使用并行数组中的值进行排序的第一个数组。
例如,如果要开发一个纸牌游戏,您想要确保每个卡使用仅一次。 而不是生成随机数字,以检索的卡和跟踪是否已处理该卡,您可以创建可用于对此演示文稿进行排序的随机数字的并行数组。 排序此演示文稿,一旦您的应用程序可以维护的指针来指示该发牌叠上的下一步卡的索引。
下面的示例阐释了这种方法。 它定义了 Card 类表示游戏卡和 Dealer 处理一副牌组成打乱顺序的类。 Dealer 类构造函数填充两个数组︰ deck数组具有类范围,该值表示此演示文稿; 与一个本地中的所有牌 order 数组,其中包含相同数量的元素作为 deck 数组并使用随机生成的填充 Double 值。 Array.Sort(Array, Array) 然后调用方法来排序 deck 中的值基于阵列 order 数组。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 |
using System; // A class that represents an individual card in a playing deck. public class Card { public Suit Suit; public FaceValue FaceValue; public override String ToString() { return String.Format("{0:F} of {1:F}", this.FaceValue, this.Suit); } } public enum Suit { Hearts, Diamonds, Spades, Clubs }; public enum FaceValue { Ace = 1, Two, Three, Four, Five, Six, Seven, Eight, Nine, Ten, Jack, Queen, King }; public class Dealer { Random rnd; // A deck of cards, without Jokers. Card[] deck = new Card[52]; // Parallel array for sorting cards. Double[] order = new Double[52]; // A pointer to the next card to deal. int ptr = 0; // A flag to indicate the deck is used. bool mustReshuffle = false; public Dealer() { rnd = new Random(); // Initialize the deck. int deckCtr = 0; foreach (var suit in Enum.GetValues(typeof(Suit))) { foreach (var faceValue in Enum.GetValues(typeof(FaceValue))) { Card card = new Card(); card.Suit = (Suit) suit; card.FaceValue = (FaceValue) faceValue; deck[deckCtr] = card; deckCtr++; } } for (int ctr = 0; ctr < order.Length; ctr++) order[ctr] = rnd.NextDouble(); Array.Sort(order, deck); } public Card[] Deal(int numberToDeal) { if (mustReshuffle) { Console.WriteLine("There are no cards left in the deck"); return null; } Card[] cardsDealt = new Card[numberToDeal]; for (int ctr = 0; ctr < numberToDeal; ctr++) { cardsDealt[ctr] = deck[ptr]; ptr++; if (ptr == deck.Length) mustReshuffle = true; if (mustReshuffle & ctr < numberToDeal - 1) { Console.WriteLine("Can only deal the {0} cards remaining on the deck.", ctr + 1); return cardsDealt; } } return cardsDealt; } } public class Example { public static void Main() { Dealer dealer = new Dealer(); ShowCards(dealer.Deal(20)); } private static void ShowCards(Card[] cards) { foreach (var card in cards) if (card != null) Console.WriteLine("{0} of {1}", card.FaceValue, card.Suit); } } // The example displays output like the following: // Six of Diamonds // King of Clubs // Eight of Clubs // Seven of Clubs // Queen of Clubs // King of Hearts // Three of Spades // Ace of Clubs // Four of Hearts // Three of Diamonds // Nine of Diamonds // Two of Hearts // Ace of Hearts // Three of Hearts // Four of Spades // Eight of Hearts // Queen of Diamonds // Two of Clubs // Four of Diamonds // Jack of Hearts |
中的随机数字生成器的实现 Random 类不能保证在.NET framework 的主版本之间将保持不变。 因此,您不应假定同一个种子将导致不同版本的.NET Framework 中的同一个伪随机序列。
在.NET Framework 1.0 和 1.1 中,类的一个最小实现派生自 Random 需要重写 Sample 方法来定义使用新的或已修改的算法来生成随机数字。 派生的类无法再依赖于的基类实现 Random.Next(), ,Random.Next(Int32), ,Random.Next(Int32, Int32), ,NextBytes, ,和 NextDouble 方法来调用的派生的类实现 Sample 方法。
在.NET Framework 2.0 及更高版本的行为 Random.Next(), ,Random.Next(Int32, Int32), ,和 NextBytes 方法已更改,以便这些方法不一定是调用的派生的类实现 Sample 方法。 从派生类的结果是, Random ,面向.NET Framework 2.0 和更高版本还应该重写这三种方法。
下面的示例创建一个随机数生成器,并调用其 NextBytes, ,Next, ,和 NextDouble 要生成的不同范围内的随机数字序列的方法。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 |
using System; public class Class1 { public static void Main() { // Instantiate random number generator using system-supplied value as seed. Random rand = new Random(); // Generate and display 5 random byte (integer) values. byte[] bytes = new byte[4]; rand.NextBytes(bytes); Console.WriteLine("Five random byte values:"); foreach (byte byteValue in bytes) Console.Write("{0, 5}", byteValue); Console.WriteLine(); // Generate and display 5 random integers. Console.WriteLine("Five random integer values:"); for (int ctr = 0; ctr <= 4; ctr++) Console.Write("{0,15:N0}", rand.Next()); Console.WriteLine(); // Generate and display 5 random integers between 0 and 100.// Console.WriteLine("Five random integers between 0 and 100:"); for (int ctr = 0; ctr <= 4; ctr++) Console.Write("{0,8:N0}", rand.Next(101)); Console.WriteLine(); // Generate and display 5 random integers from 50 to 100. Console.WriteLine("Five random integers between 50 and 100:"); for (int ctr = 0; ctr <= 4; ctr++) Console.Write("{0,8:N0}", rand.Next(50, 101)); Console.WriteLine(); // Generate and display 5 random floating point values from 0 to 1. Console.WriteLine("Five Doubles."); for (int ctr = 0; ctr <= 4; ctr++) Console.Write("{0,8:N3}", rand.NextDouble()); Console.WriteLine(); // Generate and display 5 random floating point values from 0 to 5. Console.WriteLine("Five Doubles between 0 and 5."); for (int ctr = 0; ctr <= 4; ctr++) Console.Write("{0,8:N3}", rand.NextDouble() * 5); } } // The example displays output like the following: // Five random byte values: // 194 185 239 54 116 // Five random integer values: // 507,353,531 1,509,532,693 2,125,074,958 1,409,512,757 652,767,128 // Five random integers between 0 and 100: // 16 78 94 79 52 // Five random integers between 50 and 100: // 56 66 96 60 65 // Five Doubles. // 0.943 0.108 0.744 0.563 0.415 // Five Doubles between 0 and 5. // 2.934 3.130 0.292 1.432 4.369 |
下面的示例将生成一个随机整数,它使用索引作为从数组中检索一个字符串值。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 |
using System; public class Example { public static void Main() { Random rnd = new Random(); string[] malePetNames = { "Rufus", "Bear", "Dakota", "Fido", "Vanya", "Samuel", "Koani", "Volodya", "Prince", "Yiska" }; string[] femalePetNames = { "Maggie", "Penny", "Saya", "Princess", "Abby", "Laila", "Sadie", "Olivia", "Starlight", "Talla" }; // Generate random indexes for pet names. int mIndex = rnd.Next(malePetNames.Length); int fIndex = rnd.Next(femalePetNames.Length); // Display the result. Console.WriteLine("Suggested pet name of the day: "); Console.WriteLine(" For a male: {0}", malePetNames[mIndex]); Console.WriteLine(" For a female: {0}", femalePetNames[fIndex]); } } // The example displays the following output: // Suggested pet name of the day: // For a male: Koani // For a female: Maggie |
此类型的所有公共静态(Visual Basic 中的 已共享 在 Visual Basic 中)成员都是线程安全的。不保证所有实例成员都是线程安全的。