Random Random Random Random Class

定義

表示虛擬亂數產生器,為產生數字序列的裝置,符合隨機方式的特定統計需求。Represents a pseudo-random number generator, which is a device that produces a sequence of numbers that meet certain statistical requirements for randomness.

public ref class Random
[System.Runtime.InteropServices.ComVisible(true)]
[System.Serializable]
public class Random
type Random = class
Public Class Random
繼承
RandomRandomRandomRandom
屬性

範例

下列範例會建立單一的隨機號碼產生器並呼叫其NextBytesNext,和NextDouble方法來產生不同的範圍內的隨機數字的序列。The following example creates a single random number generator and calls its NextBytes, Next, and NextDouble methods to generate sequences of random numbers within different ranges.

using namespace System;

void main()
{
   // Instantiate random number generator using system-supplied value as seed.
   Random^ rand = gcnew Random();
   // Generate and display 5 random byte (integer) values.
   array<Byte>^ bytes = gcnew array<Byte>(4);
   rand->NextBytes(bytes);
   Console::WriteLine("Five random byte values:");
   for each (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
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[5];
      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
Module Example
   Public Sub Main()
      ' Instantiate random number generator using system-supplied value as seed.
      Dim rand As New Random()
      ' Generate and display 5 random byte (integer) values.
      Dim bytes(4) As Byte
      rand.NextBytes(bytes)
      Console.WriteLine("Five random byte values:")
      For Each byteValue As Byte In bytes
         Console.Write("{0, 5}", byteValue)
      Next
      Console.WriteLine()   
      ' Generate and display 5 random integers.
      Console.WriteLine("Five random integer values:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,15:N0}", rand.Next)
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random integers between 0 and 100.'
      Console.WriteLine("Five random integers between 0 and 100:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N0}", rand.Next(101))
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random integers from 50 to 100.
      Console.WriteLine("Five random integers between 50 and 100:")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N0}", rand.Next(50, 101))
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random floating point values from 0 to 1.
      Console.WriteLine("Five Doubles.")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N3}", rand.NextDouble())
      Next                     
      Console.WriteLine()
      ' Generate and display 5 random floating point values from 0 to 5.
      Console.WriteLine("Five Doubles between 0 and 5.")
      For ctr As Integer = 0 To 4
         Console.Write("{0,8:N3}", rand.NextDouble() * 5)
      Next                     
   End Sub
End Module
' 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

下列範例會產生隨機整數,它會做為索引來擷取陣列中的字串值。The following example generates a random integer that it uses as an index to retrieve a string value from an array.

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   array<String^>^ malePetNames = { "Rufus", "Bear", "Dakota", "Fido",
                                    "Vanya", "Samuel", "Koani", "Volodya",
                                    "Prince", "Yiska" };
   array<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
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
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim malePetNames() As String = { "Rufus", "Bear", "Dakota", "Fido", 
                                    "Vanya", "Samuel", "Koani", "Volodya", 
                                    "Prince", "Yiska" }
      Dim femalePetNames() As String = { "Maggie", "Penny", "Saya", "Princess", 
                                         "Abby", "Laila", "Sadie", "Olivia", 
                                         "Starlight", "Talla" }                                      
      
      ' Generate random indexes for pet names.
      Dim mIndex As Integer = rnd.Next(malePetNames.Length)
      Dim fIndex As Integer = 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))
   End Sub
End Module
' The example displays output like the following:
'       Suggested pet name of the day:
'          For a male:     Koani
'          For a female:   Maggie

備註

虛擬隨機數字是從一組有限的數字選擇相等的可能性。Pseudo-random numbers are chosen with equal probability from a finite set of numbers. 選取的數字不是完全隨機的因為會使用數學演算法來選取它們,但它們實際上是夠隨機。The chosen numbers are not completely random because a mathematical algorithm is used to select them, but they are sufficiently random for practical purposes. 目前的實作Random類別根據 Donald E.Knuth 的涉及刪減亂數產生器演算法的修改版本。The current implementation of the Random class is based on a modified version of Donald E. Knuth's subtractive random number generator algorithm. 如需詳細資訊,請參閱 < D.e。For more information, see D. E. Knuth。Knuth. 電腦程式設計,磁碟區 2 的藝術:Seminumerical 演算法The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-wesley,讀取拼湊的麻薩諸塞州,第三個版本,1997年。Addison-Wesley, Reading, MA, third edition, 1997.

若要產生的密碼編譯安全隨機數字,例如另一個則是適合用來建立隨機的密碼,使用RNGCryptoServiceProvider類別或衍生的類別System.Security.Cryptography.RandomNumberGeneratorTo generate a cryptographically secure random number, such as one that's suitable for creating a random password, use the RNGCryptoServiceProvider class or derive a class from System.Security.Cryptography.RandomNumberGenerator.

本主題內容:In this topic:

具現化之隨機號碼產生器 Instantiating the random number generator
避免多個具現化 Avoiding multiple instantiations
System.Random 類別和執行緒安全 The System.Random class and thread safety
產生不同類型的隨機數字 Generating different types of random numbers
取代您自己的演算法 Substituting your own algorithm
您要如何使用以 System.Random... How do you use System.Random to…
擷取相同的隨機值序列Retrieve the same sequence of random values
擷取隨機值的唯一的序列Retrieve unique sequences of random values
擷取指定範圍內的整數Retrieve integers in a specified range
擷取具有指定位數的整數Retrieve integers with a specified number of digits
擷取指定範圍中的浮點值Retrieve floating-point values in a specified range
產生隨機的布林值Generate random Boolean values
產生隨機的 64 位元整數Generate random 64-bit integers
擷取指定範圍內的位元組Retrieve bytes in a specified range
從陣列或集合中隨機擷取項目Retrieve an element from an array or collection at random
擷取陣列或集合的唯一項目Retrieve a unique element from an array or collection

具現化之隨機號碼產生器Instantiating the random number generator

您具現化之隨機號碼產生器所提供的種子值 (虛擬亂數產生演算法的起始值) 來Random類別建構函式。You instantiate the random number generator by providing a seed value (a starting value for the pseudo-random number generation algorithm) to a Random class constructor. 您可以在明確或隱含提供的種子值:You can supply the seed value either explicitly or implicitly:

  • Random(Int32)建構函式會使用您提供明確的種子值。The Random(Int32) constructor uses an explicit seed value that you supply.

  • Random()建構函式會使用系統時鐘來提供的種子值。The Random() constructor uses the system clock to provide a seed value. 這是最常見的方法具現化之隨機號碼產生器。This is the most common way of instantiating the random number generator.

如果相同的種子用於個別Random物件,則會產生隨機數字的數列相同。If the same seed is used for separate Random objects, they will generate the same series of random numbers. 這可以是用來建立測試套件,以處理隨機值,或重新執行其資料源自隨機數字的遊戲。This can be useful for creating a test suite that processes random values, or for replaying games that derive their data from random numbers. 但請注意,Random不同版本的.NET Framework 下執行的處理序中的物件可能會傳回不同系列的隨機數字,即使它們具現化具有相同的種子值。However, note that Random objects in processes running under different versions of the .NET Framework may return different series of random numbers even if they're instantiated with identical seed values.

若要產生隨機數字的不同時序,您可以進行的種子值時間而異,因而產生不同的系列的每個新執行個體RandomTo produce different sequences of random numbers, you can make the seed value time-dependent, thereby producing a different series with each new instance of Random. 參數化Random(Int32)建構函式可以採用Int32值根據刻度數,在目前的時間,而無參數Random()建構函式會使用系統時鐘來產生其種子值。The parameterized Random(Int32) constructor can take an Int32 value based on the number of ticks in the current time, whereas the parameterless Random() constructor uses the system clock to generate its seed value. 不過,因為時鐘的解析度有限,使用無參數建構函式來建立不同Random中連續物件建立亂數產生器產生的隨機數字的相同順序。However, because the clock has finite resolution, using the parameterless constructor to create different Random objects in close succession creates random number generators that produce identical sequences of random numbers. 下列範例說明如何在兩個Random關閉連續具現化的物件產生相同的系列的隨機數字。The following example illustrates how two Random objects that are instantiated in close succession generate an identical series of random numbers. 在大多數的 Windows 系統Random中 15 毫秒的另一個建立的物件可能會有相同的種子值。On most Windows systems, Random objects created within 15 milliseconds of one another are likely to have identical seed values.

using namespace System;

void main()
{
   array<Byte>^ bytes1 = gcnew array<Byte>(100);
   array<Byte>^ bytes2 = gcnew array<Byte>(100);
   Random^ rnd1 = gcnew Random();
   Random^ rnd2 = gcnew 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        
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        
Module modMain

   Public Sub Main()
      Dim bytes1(99), bytes2(99) As Byte
      Dim rnd1 As New Random()
      Dim rnd2 As New Random()
      
      rnd1.NextBytes(bytes1)
      rnd2.NextBytes(bytes2)
      
      Console.WriteLine("First Series:")
      For ctr As Integer = bytes1.GetLowerBound(0) to bytes1.GetUpperBound(0)
         Console.Write("{0, 5}", bytes1(ctr))
         If (ctr + 1) Mod 10 = 0 Then Console.WriteLine()
      Next 
      Console.WriteLine()
      Console.WriteLine("Second Series:")        
      For ctr As Integer = bytes2.GetLowerBound(0) to bytes2.GetUpperBound(0)
         Console.Write("{0, 5}", bytes2(ctr))
         If (ctr + 1) Mod 10 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' 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而不是多個物件的物件。To avoid this problem, create a single Random object instead of multiple objects.

避免多個具現化Avoiding multiple instantiations

初始化兩個亂數產生器在緊密迴圈中,或快速地連續建立兩個亂數產生器可能會產生相同的隨機數字的序列。Initializing two random number generators in a tight loop or in rapid succession creates two random number generators that can produce identical sequences of random numbers. 在大部分情況下,這不是開發人員的意圖,並可能會導致效能問題,因為具現化並初始化亂數產生器是相當耗成本的程序。In most cases, this is not the developer's intent and can lead to performance issues, because instantiating and initializing a random number generator is a relatively expensive process.

同時以改善效能並避免不小心建立個別的亂數產生器,產生相同的數字序列,我們建議您建立一個Random物件來產生許多隨機的數字一段時間,而不是建立新Random產生一個隨機數字的物件。Both to improve performance and to avoid inadvertently creating separate random number generators that generate identical numeric sequences, we recommend that you create one Random object to generate many random numbers over time, instead of creating new Random objects to generate one random number.

不過,Random類別不具備執行緒安全。However, the Random class isn't thread safe. 如果您呼叫Random方法,從多個執行緒,請遵循下一節所述的指導方針。If you call Random methods from multiple threads, follow the guidelines discussed in the next section.

System.Random 類別和執行緒安全The System.Random class and thread safety

而不是具現化的個別Random物件,我們建議您建立單一Random產生應用程式所需的所有隨機數字的執行個體。Instead of instantiating individual Random objects, we recommend that you create a single Random instance to generate all the random numbers needed by your app. 不過,Random物件不是安全執行緒。However, Random objects are not thread safe. 如果您的應用程式呼叫Random從多個執行緒的方法,您必須使用同步物件來確保只有一個執行緒可以存取一次的亂數產生器。If your app calls Random methods from multiple threads, you must use a synchronization object to ensure that only one thread can access the random number generator at a time. 如果您不確定Random執行緒安全的方式存取物件時,會傳回隨機數字的方法呼叫會傳回 0。If you don't ensure that the Random object is accessed in a thread-safe way, calls to methods that return random numbers return 0.

下列範例會使用 C# lock 陳述式和 Visual Basic SyncLock 陳述式確保單一亂數產生器的 11 個執行緒存取具備執行緒安全的方式。The following example uses the C# lock Statement and the Visual Basic SyncLock statement to ensure that a single random number generator is accessed by 11 threads in a thread-safe manner. 每個執行緒會產生 2 百萬個隨機數字、 計算產生的隨機數字的數目和計算其總和,並完成執行時,然後更新所有執行緒的總計。Each thread generates 2 million random numbers, counts the number of random numbers generated and calculates their sum, and then updates the totals for all threads when it finishes executing.

using namespace System;
using namespace System::Threading;

ref class Example
{
private:
   [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;
   static Object^ numericLock;
   static Random^ rand;
   double totalValue = 0.0;
   int totalCount = 0;
   
public:
   Example()
   { 
      rand = gcnew Random();
      randLock = gcnew Object();
      numericLock = gcnew Object();
      countdown = gcnew CountdownEvent(1);
      source = gcnew CancellationTokenSource();
   } 

   void Execute()
   {   
      CancellationToken^ token = source->Token;

      for (int threads = 1; threads <= 10; threads++)
      {
         Thread^ newThread = gcnew Thread(gcnew ParameterizedThreadStart(this, &Example::GetRandomNumbers));
         newThread->Name = threads.ToString();
         newThread->Start(token);
      }
      this->GetRandomNumbers(token);
      
      countdown->Signal();
      // Make sure all threads have finished.
      countdown->Wait();

      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();

            Monitor::Enter(randLock);
            result = rand->NextDouble();
            Monitor::Exit(randLock);
            // 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.
         Monitor::Enter(numericLock);
         totalCount += perThreadCtr;
         totalValue += perThreadTotal;  
         Monitor::Exit(numericLock);
      }
      catch (OperationCanceledException^ e) {
         Console::WriteLine("Corruption in Thread {1}", e->GetType()->Name,
                            Thread::CurrentThread->Name);
      }
      finally {
         countdown->Signal();
      }
   }
};

void main()
{
   Example^ ex = gcnew Example();
   Thread::CurrentThread->Name = "Main";
   ex->Execute();
}
// 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
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
Imports System.Threading

Module Example
   <ThreadStatic> Dim previous As Double = 0.0
   <ThreadStatic> Dim perThreadCtr As Integer = 0
   <ThreadStatic> Dim perThreadTotal As Double = 0.0  
   Dim source As New CancellationTokenSource()
   Dim countdown As New CountdownEvent(1) 
   Dim randLock As New Object()
   Dim numericLock As New Object()
   Dim rand As New Random()
   Dim totalValue As Double = 0.0
   Dim totalCount As Integer = 0
   
   Public Sub Main()
      Thread.CurrentThread.Name = "Main"

      Dim token As CancellationToken = source.Token 
      For threads As Integer = 1 To 10
         Dim newThread As New Thread(AddressOf GetRandomNumbers)
         newThread.Name = threads.ToString()
         newThread.Start(token)
      Next
      GetRandomNumbers(token)
      
      countdown.Signal()
      ' Make sure all threads have finished.
      countdown.Wait()

      Console.WriteLine()
      Console.WriteLine("Total 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)
   End Sub

   Private Sub GetRandomNumbers(o As Object)
      Dim token As CancellationToken = CType(o, CancellationToken)
      Dim result As Double = 0.0
      countdown.AddCount(1)
         
      Try  
         For ctr As Integer = 1 To 2000000
            ' Make sure there's no corruption of Random.
            token.ThrowIfCancellationRequested()

            SyncLock randLock
               result = rand.NextDouble()
            End SyncLock
            ' Check for corruption of Random instance.
            If result = previous AndAlso result = 0 Then 
               source.Cancel()
            Else 
               previous = result
            End If
            perThreadCtr += 1
            perThreadTotal += result
         Next      
       
         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}", perThreadTotal/perThreadCtr)
         Console.WriteLine()
         
         ' Update overall totals.
         SyncLock numericLock
            totalCount += perThreadCtr
            totalValue += perThreadTotal  
         End SyncLock
      Catch e As OperationCanceledException
         Console.WriteLine("Corruption in Thread {1}", e.GetType().Name, Thread.CurrentThread.Name)
      Finally 
         countdown.Signal()
         source.Dispose()
      End Try
   End Sub
End Module
' 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

範例會確保執行緒安全性,以下列方式:The example ensures thread-safety in the following ways:

  • ThreadStaticAttribute屬性用來定義執行緒區域變數,可追蹤產生的隨機數字和其總和的每個執行緒的總數。The ThreadStaticAttribute attribute is used to define thread-local variables that track the total number of random numbers generated and their sum for each thread.

  • 鎖定 ( lock C# 中的陳述式和SyncLockVisual Basic 中的陳述式) 可保護變數的存取權的總計數和所有產生的所有執行緒上的隨機數字的總和。A lock (the lock statement in C# and the SyncLock statement in Visual Basic) protects access to the variables for the total count and sum of all random numbers generated on all threads.

  • 號誌 (CountdownEvent物件) 用來確保主要執行緒會封鎖直到所有其他執行緒完成執行。A semaphore (the CountdownEvent object) is used to ensure that the main thread blocks until all other threads complete execution.

  • 此範例會檢查是否隨機號碼產生器已損毀藉由判斷是否要隨機數字產生方法的兩個連續呼叫會傳回 0。The example checks whether the random number generator has become corrupted by determining whether two consecutive calls to random number generation methods return 0. 如果偵測到損毀時,此範例會使用CancellationTokenSource發出信號,表示應該取消所有執行緒的物件。If corruption is detected, the example uses the CancellationTokenSource object to signal that all threads should be canceled.

  • 才會產生每個隨機數字,每個執行緒檢查狀態CancellationToken物件。Before generating each random number, each thread checks the state of the CancellationToken object. 如果要求取消,則此範例會呼叫CancellationToken.ThrowIfCancellationRequested方法來取消執行緒。If cancellation is requested, the example calls the CancellationToken.ThrowIfCancellationRequested method to cancel the thread.

下列範例等同於第一天,不同之處在於它會使用Task物件,而不是 lambda 運算式Thread物件。The following example is identical to the first, except that it uses a Task object and a lambda expression instead of Thread objects.

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 async Task Main()
   {
      Example ex = new Example();
      Thread.CurrentThread.Name = "Main";
      await ex.Execute();
   }

   private Task 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 {
         await Task.WhenAll(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
Imports System.Collections.Generic
Imports System.Threading
Imports System.Threading.Tasks

Module Example
   Dim source As New CancellationTokenSource()
   Dim randLock As New Object()
   Dim numericLock As New Object()
   Dim rand As New Random()
   Dim totalValue As Double = 0.0
   Dim totalCount As Integer = 0
   
   Public Sub Main()
      Dim tasks As New List(Of Task)()
      
      For ctr As Integer = 1 To 10
         Dim token As CancellationToken = source.Token 
         Dim taskNo As Integer = ctr
         tasks.Add(Task.Run( 
                   Sub()
                      Dim previous As Double = 0.0
                      Dim taskCtr As Integer = 0
                      Dim taskTotal As Double = 0.0
                      Dim result As Double = 0.0

                      For n As Integer = 1 To 2000000
                         ' Make sure there's no corruption of Random.
                         token.ThrowIfCancellationRequested()
      
                         SyncLock randLock
                           result = rand.NextDouble()
                         End SyncLock
                         ' Check for corruption of Random instance.
                         If result = previous AndAlso result = 0 Then
                           source.Cancel()
                         Else 
                           previous = result
                         End If
                        taskCtr += 1
                        taskTotal += result
                      Next   

                      ' 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}", taskTotal/taskCtr)
                     Console.WriteLine()
                     
                     ' Update overall totals.
                     SyncLock numericLock
                        totalCount += taskCtr
                        totalValue += taskTotal  
                     End SyncLock
                   End Sub, token))
      Next

      Try
         Task.WaitAll(tasks.ToArray())
         Console.WriteLine()
         Console.WriteLine("Total 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 e As AggregateException
         For Each inner As Exception In e.InnerExceptions
            Dim canc As TaskCanceledException = TryCast(inner, TaskCanceledException)
            If canc IsNot Nothing Then
               Console.WriteLine("Task #{0} cancelled.", canc.Task.Id)
            Else
               Console.WriteLine("Exception: {0}", inner.GetType().Name)
            End If   
         Next         
      Finally
         source.Dispose()
      End Try
   End Sub
End Module
' 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

不同於第一個範例如下:It differs from the first example in the following ways:

  • 這樣就不需要使用變數來追蹤產生的隨機數字的數目,以及每個工作中的其總和都是本機工作,ThreadStaticAttribute屬性。The variables to keep track of the number of random numbers generated and their sum in each task are local to the task, so there is no need to use the ThreadStaticAttribute attribute.

  • 靜態Task.WaitAll方法用來確保不會完成主執行緒,才能完成所有工作。The static Task.WaitAll method is used to ensure that the main thread doesn't complete before all tasks have finished. 不需要針對CountdownEvent物件。There is no need for the CountdownEvent object.

  • 所產生的工作取消的例外狀況會顯示在Task.WaitAll方法。The exception that results from task cancellation is surfaced in the Task.WaitAll method. 在上述範例中,它是由每個執行緒處理。In the previous example, it is handled by each thread.

產生不同類型的隨機數字Generating different types of random numbers

亂數產生器會提供方法,讓您產生下列類型的隨機數字:The random number generator provides methods that let you generate the following kinds of random numbers:

  • 一系列的Byte值。A series of Byte values. 您傳遞陣列初始化為您想要返回方法的項目數目來判斷位元組值的數目NextBytes方法。You determine the number of byte values by passing an array initialized to the number of elements you want the method to return to the NextBytes method. 下列範例會產生 20 個位元組。The following example generates 20 bytes.

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew Random();
       array<Byte>^ bytes = gcnew array<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
    
    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
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          Dim bytes(19) As Byte
          rnd.NextBytes(bytes)  
          For ctr As Integer = 1 To bytes.Length
             Console.Write("{0,3}   ", bytes(ctr - 1))
             If ctr Mod 10 = 0 Then Console.WriteLine()
          Next 
       End Sub
    End Module
    ' 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
    
  • 單一的整數。A single integer. 您可以選擇是否要從 0 到最大值的整數 (Int32.MaxValue -1) 藉由呼叫Next()方法中,整數介於 0 到特定的值,藉由呼叫Next(Int32)方法或藉由呼叫值的範圍內的整數Next(Int32, Int32)方法。You can choose whether you want an integer from 0 to a maximum value (Int32.MaxValue - 1) by calling the Next() method, an integer between 0 and a specific value by calling the Next(Int32) method, or an integer within a range of values by calling the Next(Int32, Int32) method. 參數化的多載,在指定的最大值是獨佔;也就是說,產生的實際數目上限是其中一個指定的值大於或等於。In the parameterized overloads, the specified maximum value is exclusive; that is, the actual maximum number generated is one less than the specified value.

    下列範例會呼叫Next(Int32, Int32)方法,以產生 10 個隨機數字,介於-10 到 10 之間。The following example calls the Next(Int32, Int32) method to generate 10 random numbers between -10 and 10. 請注意,此方法的第二個引數指定範圍的方法所傳回的隨機值的獨佔上限。Note that the second argument to the method specifies the exclusive upper bound of the range of random values returned by the method. 換句話說,這個方法會傳回一個的最大整數低於此數的值。In other words, the largest integer that the method can return is one less than this value.

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew 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
    
    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
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          For ctr As Integer = 0 To 9
             Console.Write("{0,3}   ", rnd.Next(-10, 11))
          Next
       End Sub
    End Module
    ' The example displays output like the following:
    '    2     9    -3     2     4    -7    -3    -8    -8     5
    
  • 從 0.0 到小於 1.0 藉由呼叫的單一浮點值NextDouble方法。A single floating-point value from 0.0 to less than 1.0 by calling the NextDouble method. 方法所傳回之亂數的獨佔上限會是 1,所以它實際的上限是 0.99999999999999978。The exclusive upper bound of the random number returned by the method is 1, so its actual upper bound is 0.99999999999999978. 下列範例會產生 10 個隨機浮點數。The following example generates 10 random floating-point numbers.

    using namespace System;
    
    void main()
    {
       Random^ rnd = gcnew 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
    
    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
    
    Module Example
       Public Sub Main()
          Dim rnd As New Random()
          For ctr As Integer = 0 To 9
             Console.Write("{0,-19:R}   ", rnd.NextDouble())
             If (ctr + 1) Mod 3 = 0 Then Console.WriteLine()
          Next
       End Sub
    End Module
    ' 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)方法可讓您指定傳回的隨機數字的範圍。The Next(Int32, Int32) method allows you to specify the range of the returned random number. 不過,maxValue參數,指定較高的範圍傳回數字,其是獨佔,不含值。However, the maxValue parameter, which specifies the upper range returned number, is an exclusive, not an inclusive, value. 這表示在方法呼叫Next(0, 100)傳回值,介於 0 到 99,並不是介於 0 到 100 之間。This means that the method call Next(0, 100) returns a value between 0 and 99, and not between 0 and 100.

您也可以使用Random這類工作產生的類別隨機 t: system.boolean< 值、 產生值範圍以外的 0 到 1 的隨機浮點數,產生隨機的 64 位元整數,並隨機從陣列或集合中擷取的唯一項目You can also use the Random class for such tasks as generating random T:System.Boolean values, generating random floating point values with a range other than 0 to 1, generating random 64-bit integers, and randomly retrieving a unique element from an array or collection. 如需這些和其他一般工作,請參閱您該如何使用以 System.Random...For these and other common tasks, see the How do you use System.Random to… 一節。section.

取代您自己的演算法Substituting your own algorithm

您可以藉由繼承自實作您自己亂數產生器Random類別,並提供您亂數產生演算法。You can implement your own random number generator by inheriting from the Random class and supplying your random number generation algorithm. 若要提供您自己的演算法,您必須覆寫Sample方法,它會實作隨機的數字產生演算法。To supply your own algorithm, you must override the Sample method, which implements the random number generation algorithm. 您也應該覆寫Next()Next(Int32, Int32),並NextBytes方法,以確保它們呼叫覆寫Sample方法。You should also override the Next(), Next(Int32, Int32), and NextBytes methods to ensure that they call your overridden Sample method. 您不需要覆寫Next(Int32)NextDouble方法。You don't have to override the Next(Int32) and NextDouble methods.

如需範例衍生自Random類別,並修改其預設虛擬亂數產生器,請參閱Sample參考頁面。For an example that derives from the Random class and modifies its default pseudo-random number generator, see the Sample reference page.

您要如何使用以 System.Random...How do you use System.Random to…

下列各節討論,並提供一些您可能想要使用應用程式中的隨機數字的方式的範例程式碼。The following sections discuss and provide sample code for some of the ways you might want to use random numbers in your app.

擷取相同的隨機值序列Retrieve the same sequence of random values

有時您想要在軟體測試案例和遊戲播放產生相同的隨機數字序列。Sometimes you want to generate the same sequence of random numbers in software test scenarios and in game playing. 使用相同的隨機數字順序進行測試,可讓您偵測迴歸,並確認 bug 修正。Testing with the same sequence of random numbers allows you to detect regressions and confirm bug fixes. 在遊戲中使用相同的隨機數字序列,可讓您重新執行先前的遊戲。Using the same sequence of random number in games allows you to replay previous games.

您可以藉由提供相同的初始值,以產生相同的隨機數字序列Random(Int32)建構函式。You can generate the same sequence of random numbers by providing the same seed value to the Random(Int32) constructor. 種子值提供的虛擬隨機的數字產生演算法的起始值。The seed value provides a starting value for the pseudo-random number generation algorithm. 下列範例使用為任意的種子值來具現化 100100Random物件,會顯示 20 個隨機浮點值,並保存的種子值。The following example uses 100100 as an arbitrary seed value to instantiate the Random object, displays 20 random floating-point values, and persists the seed value. 然後將還原的種子值,會具現化新的隨機數字產生器,並會顯示相同的 20 個隨機浮點值。It then restores the seed value, instantiates a new random number generator, and displays the same 20 random floating-point values. 請注意此範例可能會產生隨機數字的不同時序,是否在不同版本的.NET Framework 上執行。Note that the example may produce different sequences of random numbers if run on different versions of the .NET Framework.

using namespace System;
using namespace System::IO;

ref class RandomMethods
{
internal:
   static void ShowRandomNumbers(int seed)
   {
      Random^ rnd = gcnew Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console::WriteLine(rnd->NextDouble());
   }
   
   static void PersistSeed(int seed)
   {
      FileStream^ fs = gcnew FileStream(".\\seed.dat", FileMode::Create);
      BinaryWriter^ bin = gcnew BinaryWriter(fs);
      bin->Write(seed);
      bin->Close();
   }
   
   static void DisplayNewRandomNumbers()
   {
      FileStream^ fs = gcnew FileStream(".\\seed.dat", FileMode::Open);
      BinaryReader^ bin = gcnew BinaryReader(fs);
      int seed = bin->ReadInt32();
      bin->Close();
      
      Random^ rnd = gcnew Random(seed);
      for (int ctr = 0; ctr <= 20; ctr++)
         Console::WriteLine(rnd->NextDouble());
   }
};

void main()
{
   int seed = 100100;
   RandomMethods::ShowRandomNumbers(seed);
   Console::WriteLine();

   RandomMethods::PersistSeed(seed);

   RandomMethods::DisplayNewRandomNumbers();
}
// 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
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
Imports System.IO

Module Example
   Public Sub Main()
      Dim seed As Integer = 100100
      ShowRandomNumbers(seed)
      Console.WriteLine()
      
      PersistSeed(seed)
      
      DisplayNewRandomNumbers() 
   End Sub
   
   Private Sub ShowRandomNumbers(seed As Integer)
      Dim rnd As New Random(seed)
      For ctr As Integer = 0 To 20
         Console.WriteLine(rnd.NextDouble())
      Next
   End Sub
   
   Private Sub PersistSeed(seed As Integer)
      Dim fs As New FileStream(".\seed.dat", FileMode.Create)
      Dim bin As New BinaryWriter(fs)
      bin.Write(seed)
      bin.Close()
   End Sub
   
   Private Sub DisplayNewRandomNumbers()
      Dim fs As New FileStream(".\seed.dat", FileMode.Open)
      Dim bin As New BinaryReader(fs)
      Dim seed As Integer = bin.ReadInt32()
      bin.Close()
      
      Dim rnd As New Random(seed)
      For ctr As Integer = 0 To 20
         Console.WriteLine(rnd.NextDouble())
      Next
   End Sub
End Module
' 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

擷取隨機數字的唯一的序列Retrieve unique sequences of random numbers

提供的執行個體的不同的種子值Random類別會導致每個亂數產生器來產生不同的一連串的值。Providing different seed values to instances of the Random class causes each random number generator to produce a different sequence of values. 您可以明確地呼叫其中一個提供初始值Random(Int32)建構函式,或以隱含方式呼叫Random()建構函式。You can provide a seed value either explicitly by calling the Random(Int32) constructor, or implicitly by calling the Random() constructor. 大部分的開發人員呼叫無參數建構函式,它會使用系統時鐘。Most developers call the parameterless constructor, which uses the system clock. 下列範例會使用這種方法來具現化兩個Random執行個體。The following example uses this approach to instantiate two Random instances. 每個執行個體顯示一系列的 10 個隨機整數。Each instance displays a series of 10 random integers.

using namespace System;
using namespace System::Threading;

void main()
{
   Console::WriteLine("Instantiating two random number generators...");
   Random^ rnd1 = gcnew Random();
   Thread::Sleep(2000);
   Random^ rnd2 = gcnew 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
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
Imports System.Threading

Module Example
   Public Sub Main()
      Console.WriteLine("Instantiating two random number generators...")
      Dim rnd1 As New Random()
      Thread.Sleep(2000)
      Dim rnd2 As New Random()
      Console.WriteLine()
      
      Console.WriteLine("The first random number generator:")
      For ctr As Integer = 1 To 10
         Console.WriteLine("   {0}", rnd1.Next())
      Next  
      Console.WriteLine()
       
      Console.WriteLine("The second random number generator:")
      For ctr As Integer = 1 To 10
         Console.WriteLine("   {0}", rnd2.Next())
      Next   
   End Sub
End Module
' 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 毫秒的時間差異。However, because of its finite resolution, the system clock doesn't detect time differences that are less than approximately 15 milliseconds. 因此,如果您的程式碼會呼叫Random()具現化兩個多載Random物件連續,您可能會不小心提供的物件具有相同的種子值。Therefore, if your code calls the Random() overload to instantiate two Random objects in succession, you might inadvertently be providing the objects with identical seed values. 若要查看這在上述範例中,標記為註解Thread.Sleep方法呼叫,並編譯和執行一次的範例。To see this in the previous example, comment out the Thread.Sleep method call, and compile and run the example again.

若要避免這種情況,我們建議您具現化一個Random物件而不是多個項目。To prevent this from happening, we recommend that you instantiate a single Random object rather than multiple ones. 不過,由於Random不具備執行緒安全,您必須使用一些同步處理的裝置,如果您存取Random執行個體從多個執行緒; 如需詳細資訊,請參閱隨機的類別和執行緒安全稍早在此主題。However, since Random isn't thread safe, you must use some synchronization device if you access a Random instance from multiple threads; for more information, see The Random class and thread safety earlier in this topic. 或者,您可以使用延遲機制,例如Sleep方法在先前範例中,用以確保具現化不會發生相差超過 15 毫秒。Alternately, you can use a delay mechanism, such as the Sleep method used in the previous example, to ensure that the instantiations occur more than 15 millisecond apart.

擷取指定範圍內的整數Retrieve integers in a specified range

您可以呼叫來擷取指定範圍內的整數Next(Int32, Int32)方法,可讓您指定下限和上限,您想要傳回之隨機號碼產生器的數字。You can retrieve integers in a specified range by calling the Next(Int32, Int32) method, which lets you specify both the lower and the upper bound of the numbers you'd like the random number generator to return. 上限是獨佔,不含值。The upper bound is an exclusive, not an inclusive, value. 也就是說,它不包含範圍內的方法所傳回的值。That is, it isn't included in the range of values returned by the method. 下列範例會使用這個方法來產生介於-10 到 10 之間的隨機整數。The following example uses this method to generate random integers between -10 and 10. 請注意,它指定 11 中,這是一必須大於想要的值,做為值的maxValue方法呼叫中的引數。Note that it specifies 11, which is one greater than the desired value, as the value of the maxValue argument in the method call.

using namespace System;

void main()
{
   Random^ rnd = gcnew 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
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
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 15
         Console.Write("{0,3}    ", rnd.Next(-10, 11))
         If ctr Mod 5 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' The example displays output like the following:
'        -2     -5     -1     -2     10
'        -3      6     -4     -8      3
'        -7     10      5     -2      4

擷取具有指定位數的整數Retrieve integers with a specified number of digits

您可以呼叫Next(Int32, Int32)方法來擷取具有指定位數的數字。You can call the Next(Int32, Int32) method to retrieve numbers with a specified number of digits. 例如,若要擷取具有四個位數 (也就是數字,範圍從 1000年到 9999) 的數字,您呼叫Next(Int32, Int32)方法minValue1000年的值和maxValue10000,如下列範例所示的值。For example, to retrieve numbers with four digits (that is, numbers that range from 1000 to 9999), you call the Next(Int32, Int32) method with a minValue value of 1000 and a maxValue value of 10000, as the following example shows.

using namespace System;

void main()
{
   Random^ rnd = gcnew 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
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
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 50
         Console.Write("{0,3}    ", rnd.Next(1000, 10000))
         If ctr Mod 10 = 0 Then Console.WriteLine()
      Next   
   End Sub
End Module
' 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

擷取指定範圍中的浮點值Retrieve floating-point values in a specified range

NextDouble方法會傳回隨機浮點數的值範圍從 0 到小於 1。The NextDouble method returns random floating-point values that range from 0 to less than 1. 不過,您通常會想要在其他範圍內產生隨機值。However, you'll often want to generate random values in some other range.

如果需要最小和最大的值之間的間隔為 1 時,您可以新增想要的啟動間隔與 0 之間的差異所傳回的數字NextDouble方法。If the interval between the minimum and maximum desired values is 1, you can add the difference between the desired starting interval and 0 to the number returned by the NextDouble method. 下列範例會產生 10 個隨機數字,介於-1 和 0。The following example does this to generate 10 random numbers between -1 and 0.

using namespace System;

void main()
{
   Random^ rnd = gcnew 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
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
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      For ctr As Integer = 1 To 10
         Console.WriteLine(rnd.NextDouble() - 1)
      Next
   End Sub
End Module
' 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),乘以非零繫結中的隨機數字。To generate random floating-point numbers whose lower bound is 0 but upper bound is greater than 1 (or, in the case of negative numbers, whose lower bound is less than -1 and upper bound is 0), multiply the random number by the non-zero bound. 下列範例會產生 20 萬個隨機浮點數的數字範圍從 0 到Int64.MaxValueThe following example does this to generate 20 million random floating-point numbers that range from 0 to Int64.MaxValue. 中也會顯示方法所產生的隨機值的分佈。In also displays the distribution of the random values generated by the method.

using namespace System;

void main()
{
   const Int64 ONE_TENTH = 922337203685477581;
   Random^ rnd = gcnew Random();
   double number;
   array<int>^ count = gcnew array<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.
      int value = (int) (number / ONE_TENTH);
      count[value]++;
   }

   // 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 %
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 %
Module Example
   Public Sub Main()
      Const ONE_TENTH As Long = 922337203685477581

      Dim rnd As New Random()
      Dim number As Long
      Dim count(9) As Integer
      
      ' Generate 20 million integer values.
      For ctr As Integer = 1 To 20000000
         number = CLng(rnd.NextDouble() * Int64.MaxValue)
         ' Categorize random numbers.
         count(CInt(number \ ONE_TENTH)) += 1
      Next
      ' Display breakdown by range.
      Console.WriteLine("{0,28} {1,32}   {2,7}", "Range", "Count", "Pct.")
      Console.WriteLine()
      For ctr As Integer = 0 To 9
         Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                            If(ctr < 9, ctr * ONE_TENTH + ONE_TENTH - 1, Int64.MaxValue), 
                            count(ctr), count(ctr)/20000000)
      Next
   End Sub
End Module
' 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)方法會為整數,請使用下列公式:To generate random floating-point numbers between two arbitrary values, like the Next(Int32, Int32) method does for integers, use the following formula:

Random.NextDouble() * (maxValue - minValue) + minValue  

下列範例會產生 1 百萬個亂數的範圍則是從 10.0 為 11.0,並顯示其散發。The following example generates 1 million random numbers that range from 10.0 to 11.0, and displays their distribution.

using namespace System;

void main()
{
   Random^ rnd = gcnew Random();
   int lowerBound = 10;
   int upperBound = 11;
   array<int>^ range = gcnew array<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 %)
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 %)
Module Example
   Public Sub Main()
      Dim rnd As New Random()
      Dim lowerBound As Integer = 10
      Dim upperBound As Integer = 11
      Dim range(9) As Integer
      For ctr As Integer = 1 To 1000000
         Dim value As Double = rnd.NextDouble() * (upperBound - lowerBound) + lowerBound
         range(CInt(Math.Truncate((value - lowerBound) * 10))) += 1 
      Next
      
      For ctr As Integer = 0 To 9
         Dim lowerRange As Double = 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)
      Next 
   End Sub
End Module
' 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 %)

產生隨機的布林值Generate random Boolean values

Random類別不提供方法,可產生Boolean值。The Random class doesn't provide methods that generate Boolean values. 不過,您可以定義自己的類別或方法,若要這麼做。However, you can define your own class or method to do that. 下列範例會定義類別BooleanGenerator,具有單一方法, NextBooleanThe following example defines a class, BooleanGenerator, with a single method, NextBoolean. BooleanGenerator類別存放區Random物件做為私用變數。The BooleanGenerator class stores a Random object as a private variable. NextBoolean方法呼叫Random.Next(Int32, Int32)方法,並將結果傳遞Convert.ToBoolean(Int32)方法。The NextBoolean method calls the Random.Next(Int32, Int32) method and passes the result to the Convert.ToBoolean(Int32) method. 請注意,2 做為引數用來指定隨機數字上限。Note that 2 is used as the argument to specify the upper bound of the random number. 由於這是獨佔的值,則方法呼叫會傳回 0 或 1。Since this is an exclusive value, the method call returns either 0 or 1.

using namespace System;

public ref class BooleanGenerator
{
   private:
      Random^ rnd;

   public:
      BooleanGenerator()
      {
         rnd = gcnew Random();
      }

      bool NextBoolean()
      {
         return Convert::ToBoolean(rnd->Next(0, 2));
      }
};

void main()
{
   // Instantiate the Boolean generator.
   BooleanGenerator^ boolGen = gcnew 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));
}

// The example displays output like the following:
//       Number of true values:  500,004 (50.000 %)
//       Number of false values: 499,996 (50.000 %)
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 %)
Module Example
   Public Sub Main()
      ' Instantiate the Boolean generator.
      Dim boolGen As New BooleanGenerator()
      Dim totalTrue, totalFalse As Integer 
      
      ' Generate 1,0000 random Booleans, and keep a running total.
      For ctr As Integer = 0 To 9999999
          Dim value As Boolean = boolGen.NextBoolean()
          If value Then
             totalTrue += 1
          Else
             totalFalse += 1
          End If
      Next
      Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})", 
                        totalTrue, 
                        totalTrue/(totalTrue + totalFalse))
      Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", 
                        totalFalse, 
                        totalFalse/(totalTrue + totalFalse))
   End Sub                     
End Module

Public Class BooleanGenerator
   Dim rnd As Random
   
   Public Sub New()
      rnd = New Random()
   End Sub

   Public Function NextBoolean() As Boolean
      Return Convert.ToBoolean(rnd.Next(0, 2))
   End Function
End Class
' The example displays the following output:
'       Number of true values:  500,004 (50.000 %)
'       Number of false values: 499,996 (50.000 %)

而不是建立個別的類別,來產生隨機Boolean值,此範例可能只是定義單一方法。Instead of creating a separate class to generate random Boolean values, the example could simply have defined a single method. 在此情況下,不過,Random物件應該已定義為類別層級變數,以避免具現化新Random中每個方法呼叫的執行個體。In that case, however, the Random object should have been defined as a class-level variable to avoid instantiating a new Random instance in each method call. 在 Visual Basic 中的 Random 執行個體可以定義為靜態變數中NextBoolean方法。In Visual Basic, the Random instance can be defined as a Static variable in the NextBoolean method. 下列範例提供的實作。The following example provides an implementation.

using namespace System;

ref class Example
{
private:
   static Random^ rnd = gcnew Random();

public:
   static void Execute()
   {
      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));
   }

   static bool NextBoolean()
   {
      return Convert::ToBoolean(rnd->Next(0, 2));
   }
};

void main()
{
   Example::Execute();
}
// The example displays output like the following:
//       Number of true values:  499,777 (49.978 %)
//       Number of false values: 500,223 (50.022 %)
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 %)
Module Example
   Public Sub Main()
      Dim totalTrue, totalFalse As Integer 
      
      ' Generate 1,0000 random Booleans, and keep a running total.
      For ctr As Integer = 0 To 9999999
          Dim value As Boolean = NextBoolean()
          If value Then
             totalTrue += 1
          Else
             totalFalse += 1
          End If
      Next
      Console.WriteLine("Number of true values:  {0,7:N0} ({1:P3})", 
                        totalTrue, 
                        totalTrue/(totalTrue + totalFalse))
      Console.WriteLine("Number of false values: {0,7:N0} ({1:P3})", 
                        totalFalse, 
                        totalFalse/(totalTrue + totalFalse))
   End Sub 
                       
   Public Function NextBoolean() As Boolean
      Static rnd As New Random()
      Return Convert.ToBoolean(rnd.Next(0, 2))
   End Function
End Module
' The example displays the following output:
'       Number of true values:  499,777 (49.978 %)
'       Number of false values: 500,223 (50.022 %)

產生隨機的 64 位元整數Generate random 64-bit integers

多載Next方法會傳回 32 位元整數。The overloads of the Next method return 32-bit integers. 不過,在某些情況下,您可能想要使用 64 位元整數。However, in some cases, you might want to work with 64-bit integers. 您可以依照下列方式來執行這項操作:You can do this as follows:

  1. 呼叫NextDouble方法來擷取雙精確度浮點數的值。Call the NextDouble method to retrieve a double-precision floating point value.

  2. 將由該值乘以Int64.MaxValueMultiply that value by Int64.MaxValue.

下列範例會產生 20 萬個隨機的長整數使用這項技術,並將它們分類中 10 個相等的群組。The following example uses this technique to generate 20 million random long integers and categorizes them in 10 equal groups. 它接著會評估分佈的隨機數字,來計算從 0 到每個群組中的數字Int64.MaxValueIt then evaluates the distribution of the random numbers by counting the number in each group from 0 to Int64.MaxValue. 如範例輸出所示,數字會增加或減少平均分散整個長整數的範圍。As the output from the example shows, the numbers are distributed more or less equally through the range of a long integer.

using namespace System;

void main()
{
   const Int64 ONE_TENTH = 922337203685477581;

   Random^ rnd = gcnew Random();
   Int64 number;
   array<int>^ count = gcnew array<int>(10);
   
   // Generate 20 million long integers.
   for (int ctr = 1; ctr <= 20000000; ctr++) {
      number = (Int64) (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 %
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 %
Module Example
   Public Sub Main()
      Const ONE_TENTH As Long = 922337203685477581

      Dim rnd As New Random()
      Dim number As Long
      Dim count(9) As Integer
      
      ' Generate 20 million long integers.
      For ctr As Integer = 1 To 20000000
         number = CLng(rnd.NextDouble() * Int64.MaxValue)
         ' Categorize random numbers.
         count(CInt(number \ ONE_TENTH)) += 1
      Next
      ' Display breakdown by range.
      Console.WriteLine("{0,28} {1,32}   {2,7}", "Range", "Count", "Pct.")
      Console.WriteLine()
      For ctr As Integer = 0 To 9
         Console.WriteLine("{0,25:N0}-{1,25:N0}  {2,8:N0}   {3,7:P2}", ctr * ONE_TENTH,
                            If(ctr < 9, ctr * ONE_TENTH + ONE_TENTH - 1, Int64.MaxValue), 
                            count(ctr), count(ctr)/20000000)
      Next
   End Sub
End Module
' 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 %

替代方法,會使用位元操作不會產生真正的隨機數字。An alternative technique that uses bit manipulation does not generate truly random numbers. 這項技術會呼叫Next()來產生兩個整數、 左移一個由 32 位元為單位和 Or 在一起。This technique calls Next() to generate two integers, left-shifts one by 32 bits, and ORs them together. 這項技術有兩項限制:This technique has two limitations:

  1. 位元 31 為正負號位元,因為產生的長整數的位元 31 中的值一律是 0。Because bit 31 is the sign bit, the value in bit 31 of the resulting long integer is always 0. 這可藉由產生隨機的 0 或 1,向左移位它 31 位元為單位,並搭配使用 or 與它與原始的隨機長整數。This can be addressed by generating a random 0 or 1, left-shifting it 31 bits, and ORing it with the original random long integer.

  2. 更嚴重,因為所傳回的值的機率Next()將會是 0,如果有的話,將幾個隨機數字會出在範圍內 0x0 0x00000000FFFFFFFF。More seriously, because the probability that the value returned by Next() will be 0, there will be few if any random numbers in the range 0x0-0x00000000FFFFFFFF.

擷取指定範圍內的位元組Retrieve bytes in a specified range

多載Next方法可讓您指定的隨機數字,範圍但NextBytes方法則否。The overloads of the Next method allow you to specify the range of random numbers, but the NextBytes method does not. 下列範例會實作NextBytes方法,可讓您指定的傳回的位元組範圍。The following example implements a NextBytes method that lets you specify the range of the returned bytes. 它會定義Random2類別衍生自Random並且可以多載其NextBytes方法。It defines a Random2 class that derives from Random and overloads its NextBytes method.

using namespace System;

ref class Random2 : Random
{
public:
   Random2()
   {}

   Random2(int seed) : Random(seed)
   {}

   void NextBytes(array<Byte>^ bytes, Byte minValue, Byte maxValue)
   {
      for (int ctr = bytes->GetLowerBound(0); ctr <= bytes->GetUpperBound(0); ctr++)
         bytes[ctr] = (Byte) Next(minValue, maxValue);
   }
};

void main()
{
    Random2^ rnd = gcnew Random2();
    array<Byte>^ bytes = gcnew array<Byte>(10000);
    array<int>^ total = gcnew array<int>(101);
    rnd->NextBytes(bytes, 0, 101);

    // Calculate how many of each value we have.
    for each (Byte 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();
    }
}
// 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
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
Module Example
   Public Sub Main()
       Dim rnd As New Random2()
       Dim bytes(9999) As Byte
       Dim total(100) As Integer
       rnd.NextBytes(bytes, 0, 101)
       
       ' Calculate how many of each value we have.
       For Each value In bytes
          total(value) += 1
       Next
       
       ' Display the results.
       For ctr As Integer = 0 To total.Length - 1
           Console.Write("{0,3}: {1,-3}   ", ctr, total(ctr))
           If (ctr + 1) Mod 5 = 0 Then Console.WriteLine()
       Next   
   End Sub
End Module

Public Class Random2 : Inherits Random
   Public Sub New()
      MyBase.New()
   End Sub   

   Public Sub New(seed As Integer)
      MyBase.New(seed)
   End Sub

   Public Overloads Sub NextBytes(bytes() As Byte, 
                                  minValue As Byte, maxValue As Byte)
      For ctr As Integer = bytes.GetLowerbound(0) To bytes.GetUpperBound(0)
         bytes(ctr) = CByte(MyBase.Next(minValue, maxValue))
      Next
   End Sub
End Class 
' 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) 我們要傳回的位元組陣列中。The NextBytes(Byte[], Byte, Byte) method wraps a call to the Next(Int32, Int32) method and specifies the minimum value and one greater than the maximum value (in this case, 0 and 101) that we want returned in the byte array. 因為我們已經確定所傳回的整數值Next方法會在範圍內Byte資料型別,我們可以安全地將參數轉換 (在 C# 中) 或將它們 (在 Visual Basic 中) 從整數轉換為位元組。Because we are sure that the integer values returned by the Next method are within the range of the Byte data type, we can safely cast them (in C#) or convert them (in Visual Basic) from integers to bytes.

從陣列或集合中隨機擷取項目Retrieve an element from an array or collection at random

隨機數字通常會做為索引來擷取陣列或集合中的值。Random numbers often serve as indexes to retrieve values from arrays or collections. 若要擷取的隨機的索引值,您可以呼叫Next(Int32, Int32)方法,並使用較低的陣列繫結的值為其minValue引數和大於上限的值陣列的其中一個其maxValue引數。To retrieve a random index value, you can call the Next(Int32, Int32) method, and use the lower bound of the array as the value of its minValue argument and one greater than the upper bound of the array as the value of its maxValue argument. 以零為起始的陣列,這相當於其Length屬性,或大於所傳回的值的其中一個Array.GetUpperBound方法。For a zero-based array, this is equivalent to its Length property, or one greater than the value returned by the Array.GetUpperBound method. 隨機,下列範例會擷取在美國境內的城市名稱從陣列的城市。The following example randomly retrieves the name of a city in the United States from an array of cities.

using namespace System;

void main()
{
   array<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 = gcnew 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
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
Module Example
   Public Sub Main()
      Dim cities() As String = { "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" }
      Dim rnd As New Random()
      Dim index As Integer = rnd.Next(0, cities.Length)
      Console.WriteLine("Today's city of the day: {0}",
                        cities(index))                           
   End Sub
End Module
' The example displays output like the following:
'   Today's city of the day: Honolulu

擷取陣列或集合的唯一項目Retrieve a unique element from an array or collection

亂數產生器一律會傳回重複的值。A random number generator can always return duplicate values. 當數字範圍變得比較小,或產生的值數目變得更大,重複的可能性就會成長。As the range of numbers becomes smaller or the number of values generated becomes larger, the probability of duplicates grows. 如果隨機的值必須是唯一的更多的數字會產生補償重複項目,導致越來越不佳的效能。If random values must be unique, more numbers are generated to compensate for duplicates, resulting in increasingly poor performance.

有幾個方法來處理這種情況。There are a number of techniques to handle this scenario. 一個常用的解決方案是建立陣列或集合,其中包含要擷取的值和平行的陣列,其中包含隨機浮點數。One common solution is to create an array or collection that contains the values to be retrieved, and a parallel array that contains random floating-point numbers. 第二個陣列,會在建立第一個陣列時,填入與隨機數字和Array.Sort(Array, Array)方法用來排序第一個陣列所使用的平行陣列中的值。The second array is populated with random numbers at the time the first array is created, and the Array.Sort(Array, Array) method is used to sort the first array by using the values in the parallel array.

比方說,如果您正在開發的單人遊戲,您會想要確保每張卡片只有使用一次。For example, if you're developing a Solitaire game, you want to ensure that each card is used only once. 而不是產生隨機數字,以擷取卡片和追蹤是否已處理該卡片,您可以建立可用來排序的牌堆的隨機數字的平行陣列。Instead of generating random numbers to retrieve a card and tracking whether that card has already been dealt, you can create a parallel array of random numbers that can be used to sort the deck. 一旦已排序的投影片,您的應用程式可以維護的指標,表示下一張牌,投影片上的索引。Once the deck is sorted, your app can maintain a pointer to indicate the index of the next card on the deck.

下列範例將示範這個方法。The following example illustrates this approach. 它會定義Card類別,代表紙牌的以及Dealer處理隨機播放一疊紙牌的類別。It defines a Card class that represents a playing card and a Dealer class that deals a deck of shuffled cards. Dealer類別建構函式會填入這兩個陣列:deck陣列具有類別範圍,以及表示在牌堆; 和本機中的所有卡片order具有相同數目的項目與陣列deck陣列,而且會填入使用隨機產生Double值。The Dealer class constructor populates two arrays: a deck array that has class scope and that represents all the cards in the deck; and a local order array that has the same number of elements as the deck array and is populated with randomly generated Double values. Array.Sort(Array, Array)接著會呼叫方法來排序deck中的值為基礎的陣列order陣列。The Array.Sort(Array, Array) method is then called to sort the deck array based on the values in the order array.

using namespace System;

public enum class Suit { Hearts, Diamonds, Spades, Clubs };

public enum class FaceValue  { Ace = 1, Two, Three, Four, Five, Six,
                               Seven, Eight, Nine, Ten, Jack, Queen,
                               King };

// A class that represents an individual card in a playing deck.
ref class Card
{
public:
   Suit Suit;
   FaceValue FaceValue;
   
   String^ ToString() override
   {
      return String::Format("{0:F} of {1:F}", this->FaceValue, this->Suit);
   }
};

ref class Dealer
{
private:
   Random^ rnd;
   // A deck of cards, without Jokers.
   array<Card^>^ deck = gcnew array<Card^>(52);
   // Parallel array for sorting cards.
   array<Double>^ order = gcnew array<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 = gcnew Random();
      // Initialize the deck.
      int deckCtr = 0;
      for each (auto suit in Enum::GetValues(Suit::typeid)) {
         for each (FaceValue faceValue in Enum::GetValues(FaceValue::typeid)) {
            Card^ card = gcnew 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);
   }

   array<Card^>^ Deal(int numberToDeal)
   {
      if (mustReshuffle) {
         Console::WriteLine("There are no cards left in the deck");
         return nullptr;
      }
      
      array<Card^>^ cardsDealt = gcnew array<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;
   }
};

void ShowCards(array<Card^>^ cards)
{
   for each (Card^ card in cards)
      if (card != nullptr)
         Console::WriteLine("{0} of {1}", card->FaceValue, card->Suit);
};

void main()
{
   Dealer^ dealer = gcnew Dealer();
   ShowCards(dealer->Deal(20));
}

// 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
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
' A class that represents an individual card in a playing deck.
Public Class Card
   Public Suit As Suit
   Public FaceValue As FaceValue
   
   Public Overrides Function ToString() As String
      Return String.Format("{0:F} of {1:F}", Me.FaceValue, Me.Suit)
   End Function
End Class

Public Enum Suit As Integer
   Hearts = 0
   Diamonds = 1
   Spades = 2
   Clubs = 3
End Enum

Public Enum FaceValue As Integer
   Ace = 1
   Two = 2
   Three = 3
   Four = 4
   Five = 5
   Six = 6
   Seven = 7
   Eight = 8
   Nine = 9
   Ten = 10
   Jack = 11
   Queen = 12
   King = 13
End Enum

Public Class Dealer
   Dim rnd As Random
   ' A deck of cards, without Jokers.
   Dim deck(51) As Card
   ' Parallel array for sorting cards.
   Dim order(51) As Double
   ' A pointer to the next card to deal.
   Dim ptr As Integer = 0
   ' A flag to indicate the deck is used.
   Dim mustReshuffle As Boolean
   
   Public Sub New()
      rnd = New Random()
      ' Initialize the deck.
      Dim deckCtr As Integer = 0
      For Each Suit In [Enum].GetValues(GetType(Suit))
         For Each faceValue In [Enum].GetValues(GetType(FaceValue))
            Dim card As New Card()
            card.Suit = CType(Suit, Suit)
            card.FaceValue = CType(faceValue, FaceValue)
            deck(deckCtr) = card  
            deckCtr += 1
         Next
      Next
      For ctr As Integer = 0 To order.Length - 1
         order(ctr) = rnd.NextDouble()   
      Next   
      Array.Sort(order, deck)
   End Sub

   Public Function Deal(numberToDeal As Integer) As Card()
      If mustReshuffle Then
         Console.WriteLine("There are no cards left in the deck")
         Return Nothing
      End If
      
      Dim cardsDealt(numberToDeal - 1) As Card
      For ctr As Integer = 0 To numberToDeal - 1
         cardsDealt(ctr) = deck(ptr)
         ptr += 1
         If ptr = deck.Length Then 
            mustReshuffle = True
         End If
         If mustReshuffle And ctr < numberToDeal - 1
            Console.WriteLine("Can only deal the {0} cards remaining on the deck.", 
                              ctr + 1)
            Return cardsDealt
         End If
      Next
      Return cardsDealt
   End Function
End Class

Public Module Example
   Public Sub Main()
      Dim dealer As New Dealer()
      ShowCards(dealer.Deal(20))
   End Sub
   
   Private Sub ShowCards(cards() As Card)
      For Each card In cards
         If card IsNot Nothing Then _
            Console.WriteLine("{0} of {1}", card.FaceValue, card.Suit)
      Next
   End Sub
End Module
' 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

給繼承者的注意事項

在.NET Framework 1.0 和 1.1 中,類別的最小實作衍生自Random需要覆寫Sample()方法來定義新的或修改過的演算法來產生隨機數字。In the .NET Framework 1.0 and 1.1, a minimum implementation of a class derived from Random required overriding the Sample() method to define a new or modified algorithm for generating random numbers. 衍生的類別無法再仰賴的基底類別實作Next()Next(Int32)Next(Int32, Int32)NextBytes(Byte[]),並NextDouble()方法來呼叫的衍生的類別實作Sample()方法。The derived class could then rely on the base class implementation of the Next(), Next(Int32), Next(Int32, Int32), NextBytes(Byte[]), and NextDouble() methods to call the derived class implementation of the Sample() method.

在.NET Framework 2.0 和更新版本的行為Next()Next(Int32, Int32),並NextBytes(Byte[])方法已變更,以便讓這些方法不一定是呼叫的衍生的類別實作Sample()方法。In the .NET Framework 2.0 and later, the behavior of the Next(), Next(Int32, Int32), and NextBytes(Byte[]) methods have changed so that these methods do not necessarily call the derived class implementation of the Sample() method. 如此一來,衍生自Random的目標.NET Framework 2.0 和更新版本也會覆寫這三種方法。As a result, classes derived from Random that target the .NET Framework 2.0 and later should also override these three methods.

給呼叫者的注意事項

亂數產生器中的實作Random類別不保證維持不變的.NET framework 的主要版本。The implementation of the random number generator in the Random class isn't guaranteed to remain the same across major versions of the .NET Framework. 如此一來,您不應該假設相同的種子會導致不同版本的.NET Framework 中的相同虛擬隨機序列。As a result, you shouldn't assume that the same seed will result in the same pseudo-random sequence in different versions of the .NET Framework.

建構函式

Random() Random() Random() Random()

使用時間相依預設種子值來初始化 Random 類別的新執行個體。Initializes a new instance of the Random class, using a time-dependent default seed value.

Random(Int32) Random(Int32) Random(Int32) Random(Int32)

使用指定的種子值,初始化 Random 類別的新執行個體。Initializes a new instance of the Random class, using the specified seed value.

方法

Equals(Object) Equals(Object) Equals(Object) Equals(Object)

判斷指定的物件是否等於目前的物件。Determines whether the specified object is equal to the current object.

(Inherited from Object)
GetHashCode() GetHashCode() GetHashCode() GetHashCode()

做為預設雜湊函式。Serves as the default hash function.

(Inherited from Object)
GetType() GetType() GetType() GetType()

取得目前執行個體的 TypeGets the Type of the current instance.

(Inherited from Object)
MemberwiseClone() MemberwiseClone() MemberwiseClone() MemberwiseClone()

建立目前 Object 的淺層複製。Creates a shallow copy of the current Object.

(Inherited from Object)
Next() Next() Next() Next()

傳回非負值的隨機整數。Returns a non-negative random integer.

Next(Int32) Next(Int32) Next(Int32) Next(Int32)

傳回小於指定之最大值的非負值隨機整數。Returns a non-negative random integer that is less than the specified maximum.

Next(Int32, Int32) Next(Int32, Int32) Next(Int32, Int32) Next(Int32, Int32)

傳回指定範圍內的隨機整數。Returns a random integer that is within a specified range.

NextBytes(Byte[]) NextBytes(Byte[]) NextBytes(Byte[]) NextBytes(Byte[])

以亂數填入指定位元組陣列的元素。Fills the elements of a specified array of bytes with random numbers.

NextBytes(Span<Byte>) NextBytes(Span<Byte>) NextBytes(Span<Byte>) NextBytes(Span<Byte>)
NextDouble() NextDouble() NextDouble() NextDouble()

傳回大於或等於 0.0,且小於 1.0 的隨機浮點數。Returns a random floating-point number that is greater than or equal to 0.0, and less than 1.0.

Sample() Sample() Sample() Sample()

傳回 0.0 和 1.0 之間的隨機浮點數。Returns a random floating-point number between 0.0 and 1.0.

ToString() ToString() ToString() ToString()

傳回代表目前物件的字串。Returns a string that represents the current object.

(Inherited from Object)

適用於