Dieser Artikel wurde maschinell übersetzt. Wenn Sie die englische Version des Artikels anzeigen möchten, aktivieren Sie das Kontrollkästchen Englisch. Sie können den englischen Text auch in einem Popupfenster anzeigen, indem Sie den Mauszeiger über den Text bewegen.
Übersetzung
Englisch

Random-Klasse

 

Veröffentlicht: Oktober 2016

Stellt einen Generator für Pseudozufallszahlen dar, d. h. ein Gerät, das eine Zahlenfolge erzeugt, die bestimmte statistische Anforderungen hinsichtlich ihrer Zufälligkeit erfüllt.

Um den .NET Framework-Quellcode für diesen Typ zu durchsuchen, finden Sie unter der Reference Source.

Namespace:   System
Assembly:  mscorlib (in mscorlib.dll)


[SerializableAttribute]
[ComVisibleAttribute(true)]
public class Random

NameBeschreibung
System_CAPS_pubmethodRandom()

Initialisiert eine neue Instanz der Random -Klasse unter Verwendung eines zeitabhängigen Standardstartwerts.

System_CAPS_pubmethodRandom(Int32)

Initialisiert eine neue Instanz der Random -Klasse unter Verwendung des angegebenen Startwerts.

NameBeschreibung
System_CAPS_pubmethodEquals(Object)

Bestimmt, ob das angegebene Objekt mit dem aktuellen Objekt identisch ist.(Geerbt von „Object“.)

System_CAPS_protmethodFinalize()

Gibt einem Objekt Gelegenheit, Ressourcen freizugeben und andere Bereinigungen durchzuführen, bevor es von der Garbage Collection freigegeben wird. (Geerbt von „Object“.)

System_CAPS_pubmethodGetHashCode()

Fungiert als die Standardhashfunktion.(Geerbt von „Object“.)

System_CAPS_pubmethodGetType()

Ruft den Type der aktuellen Instanz ab.(Geerbt von „Object“.)

System_CAPS_protmethodMemberwiseClone()

Erstellt eine flache Kopie des aktuellen Object.(Geerbt von „Object“.)

System_CAPS_pubmethodNext()

Gibt eine nicht negative Zufallsganzzahl zurück.

System_CAPS_pubmethodNext(Int32)

Gibt eine nicht negative Zufallsganzzahl zurück, die kleiner als das angegebene Maximum ist.

System_CAPS_pubmethodNext(Int32, Int32)

Gibt eine Zufallsganzzahl zurück, die in einem angegebenen Bereich liegt.

System_CAPS_pubmethodNextBytes(Byte[])

Füllt die Elemente eines angegebenen Bytearrays mit Zufallszahlen.

System_CAPS_pubmethodNextDouble()

Gibt eine zufällige Gleitkommazahl zurück, die größer oder gleich 0,0 und kleiner als 1,0 ist.

System_CAPS_protmethodSample()

Gibt eine zufällige Gleitkommazahl zwischen 0,0 und 1,0 zurück.

System_CAPS_pubmethodToString()

Gibt eine Zeichenfolge zurück, die das aktuelle Objekt darstellt.(Geerbt von „Object“.)

System_CAPS_noteHinweis

Die .NET Framework-Quellcodes für diesen Typ finden Sie unter der Reference Source. Sie können den Quellcode online Durchsuchen, Referenz für die Offlineanzeige herunterladen und schrittweise durchlaufen (inklusive Patches und Updates) während des Debuggens; see instructions.

Pseudozufallszahlen werden mit gleicher Wahrscheinlichkeit aus einer endlichen Menge von Zahlen ausgewählt. Die ausgewählten Zahlen sind nicht vollständig zufällige, ein mathematischer Algorithmus wird verwendet, um sie auszuwählen, denn sie sind für praktische Zwecke ausreichend zufällig. Die aktuelle Implementierung von der Random -Klasse basiert auf einer geänderten Version der Donald E. Knuths Subtraktive Algorithmus mit Zufallszahlengenerator. Weitere Informationen finden Sie unter d E. Knuth. The Art of Computer Programming, Volume 2: Seminumerical Algorithms. Addison-Wesley, lesen, MA, 3. Ausgabe, 1997.

Verwenden, um ein kryptografisch sicheren Zufallszahl, z. B. ein generieren, die für das Erstellen eines zufälligen Kennworts, die RNGCryptoServiceProvider Klasse oder eine Klasse von System.Security.Cryptography.RandomNumberGenerator.

In diesem Thema:

Instanziieren den Zufallszahlengenerator
vermeiden mehrere Instanziierungen von
der System.Random-Klasse und Threadsicherheit
verschiedene Arten von Zufallszahlen generieren
und Ersetzen Sie dabei einen eigenen Algorithmus
Verwendung System.Random,...
Die gleiche Folge von zufälligen Werten abzurufen
eindeutige Sequenzen von zufälligen Werten abrufen
Abrufen von ganzen Zahlen in einem angegebenen Bereich
Abrufen von ganzen Zahlen mit einer angegebenen Anzahl von Ziffern
Gleitkommawerte in einem angegebenen Bereich abgerufen
generiert zufällige boolesche Werte
Generieren von zufälligen 64-Bit-Ganzzahlen
Bytes in einem angegebenen Bereich abgerufen
nach dem Zufallsprinzip ein Element aus einem Array oder einer Auflistung abrufen
ein eindeutiges Element abrufen aus einem Array oder einer Auflistung

Sie instanziieren den Zufallszahlen-Generator bietet einen Ausgangswert (einen Anfangswert für den Algorithmus von Pseudozufallszahlen Generation) zu einem Random Klassenkonstruktor. Sie können den Ausgangswert entweder explizit oder implizit angeben:

  • Die Random(Int32) -Konstruktor verwendet einen explizite Seed-Wert, den Sie angeben.

  • Die Random() Konstruktor verwendet die Systemuhr einen Ausgangswert angeben. Dies ist die gängigste Art der Instanziierung des Zufallszahlengenerators.

Wenn der gleiche Ausgangswert, für Separate verwendet wird Random Objekte, die sie der gleichen Reihe von Zufallszahlen generiert. Dies kann nützlich für das Erstellen einer Testsammlung, die zufällige Werte verarbeitet oder für die Wiedergabe von Spielen, die ihre Daten von Zufallszahlen abgeleitet sein. Beachten Sie jedoch, dass Random Objekte in Prozesse, die unter unterschiedlichen Versionen von .NET Framework möglicherweise andere Folge von Zufallszahlen zurück, auch wenn sie mit identischen Startwerten instanziiert werden.

Um verschiedene Sequenzen von Zufallszahlen zu generieren, können Sie vornehmen den Ausgangswert zeitabhängige, erzeugen und eine andere Datenreihe mit jeder neuen Instanz des Random. Die parametrisierte Random(Int32) Konstruktor akzeptiert ein Int32 Wert basierend auf der Anzahl der Ticks in der aktuellen Zeit, während die parameterlose Random() Konstruktor verwendet die Systemuhr zum Generieren des Startwerts. Aber da die Uhr endliche Auflösung hat, mithilfe des Konstruktors unterschiedlichen Random Objekte nacheinander Zufallszahlengeneratoren erstellt Zufallszahlengeneratoren, die identische Sequenzen von Zufallszahlen erzeugen. Im folgende Beispiel wird veranschaulicht, wie zwei Random -Objekte, die unmittelbar nacheinander instanziierten eine identische Folge von Zufallszahlen generieren. In den meisten Windows-Systemen Random innerhalb von 15 Millisekunden voneinander erstellten Objekte werden wahrscheinlich identischen Startwerten.

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        

Um dieses Problem zu vermeiden, erstellen Sie ein einzelnes Random Objekt anstelle mehrerer Objekte.

Initialisieren von zwei-Zufallszahlen-Generatoren in einer engen Schleife oder in rascher Folge erstellt zwei Zufallszahlengeneratoren, die identische Sequenzen von Zufallszahlen erzeugen können. In den meisten Fällen dies nicht Absicht des Entwicklers und kann zu Leistungsprobleme führen, da instanziieren und Initialisieren eines Zufallszahlen-Generators ein relativ aufwändiger Vorgang ist.

Sowohl zur Verbesserung der Leistung und verhindern, dass versehentlich erstellt separate Zufallszahlengeneratoren, die identische numerische Sequenzen zu generieren, wird empfohlen, dass Sie eine erstellen Random Objekt viele Zufallszahlen im Laufe der Zeit neue anstatt Random Objekte, um eine Zufallszahl zu generieren.

Allerdings die Random Klasse nicht threadsicher ist. Wenn Sie aufrufen Random Methoden von mehreren Threads führen Sie die Richtlinien im nächsten Abschnitt erläutert.

Anstatt einzelne Instanziierung Random Objekte, empfehlen wir, dass Sie ein einzelnes Random -Instanz, die alle von der Anwendung benötigten Zufallszahlen zu generieren. Allerdings Random Objekte sind nicht threadsicher. Wenn die app ruft Random Methoden von mehreren Threads, Sie müssen ein Synchronisierungsobjekt verwenden, um sicherzustellen, dass nur ein Thread den Zufallszahlengenerator gleichzeitig zugreifen kann. Wenn Sie nicht sicherstellen, dass die Random Objekt auf eine threadsichere Weise zugegriffen wird, Aufrufe von Methoden, die Zufallszahlen zurückgeben, geben 0 zurück.

Im folgenden Beispiel wird der C#- lock-Anweisung und Visual Basic SyncLock-Anweisung um sicherzustellen, dass ein einzelner Zufallszahlengenerator 11 Threads auf eine threadsichere Weise zugreifen. Jeder Thread 2 Millionen Zufallszahlen generiert, zählt die Anzahl der Zufallszahlen generiert und berechnet die Summe und aktualisiert dann die Gesamtwerte für alle Threads aus, wenn sie die Ausführung beendet wurde.

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

Im Beispiel wird die Threadsicherheit auf folgende Weise:

  • Die ThreadStaticAttribute Attribut wird verwendet, um die Thread-lokalen Variablen definieren, die die Gesamtanzahl der Zufallszahlen generiert und die Summe für die einzelnen Threads zu verfolgen.

  • Eine Sperre (die lock -Anweisung in c# und die SyncLock -Anweisung in Visual Basic) schützt den Zugriff auf die Variablen für die Gesamtzahl und die Summe aller zufälligen Zahlen für alle Threads generiert.

  • Ein Semaphor (die CountdownEvent Objekt) wird verwendet, um sicherzustellen, dass der Hauptthread blockiert, bis alle anderen Threads vollständig ausgeführt.

  • Im Beispiel wird überprüft, ob der Zufallszahlengenerator durch bestimmen beschädigt wurde, ob zwei aufeinander folgende Aufrufe von Zufallszahlen generieren, Methoden 0 zurück. Wenn eine Beschädigung erkannt wird, wird im Beispiel wird die CancellationTokenSource -Objekt signalisiert, dass alle Threads abgebrochen werden soll.

  • Vor jeder Zufallszahl generieren von jedem Thread überprüft den Status der CancellationToken Objekt. Wenn der Abbruch angefordert wird, ruft das Beispiel die CancellationToken.ThrowIfCancellationRequested Methode, um den Thread abzubrechen.

Im folgende Beispiel wird mit dem ersten identisch, verwendet jedoch eine Task -Objekt und ein Lambda-Ausdruck anstelle von Thread Objekte.

using System;
using System.Collections.Generic;
using System.Threading;
using System.Threading.Tasks;

public class Example
{
   static Object randLock, numericLock;
   static Random rand;
   static CancellationTokenSource source;
   double totalValue = 0.0;
   int totalCount = 0;

   public Example()
   { 
      rand = new Random();
      randLock = new Object();
      numericLock = new Object();
      source = new CancellationTokenSource();
   } 

   public static void Main()
   {
      Example ex = new Example();
      Thread.CurrentThread.Name = "Main";
      ex.Execute();
   }

   private void Execute()
   {   
      List<Task> tasks = new List<Task>();

      for (int ctr = 0; ctr <= 10; ctr++)
      {
         CancellationToken token = source.Token; 
         int taskNo = ctr;
         tasks.Add(Task.Run( () =>
            {
               double previous = 0.0;
               int taskCtr = 0;
               double taskTotal = 0.0;  
               double result = 0.0;

               for (int n = 0; n < 2000000; n++)
               {
                  // Make sure there's no corruption of Random.
                  token.ThrowIfCancellationRequested();

                  lock (randLock) {
                     result = rand.NextDouble();
                  }
                  // Check for corruption of Random instance.
                  if ((result == previous) && result == 0) {
                     source.Cancel();
                  }
                  else {
                     previous = result;
                  }
                  taskCtr++;
                  taskTotal += result;
               }

               // Show result.
               Console.WriteLine("Task {0} finished execution.", taskNo);
               Console.WriteLine("Random numbers generated: {0:N0}", taskCtr);
               Console.WriteLine("Sum of random numbers: {0:N2}", taskTotal);
               Console.WriteLine("Random number mean: {0:N4}\n", taskTotal/taskCtr);

               // Update overall totals.
               lock (numericLock) {
                  totalCount += taskCtr;
                  totalValue += taskTotal;  
               }
            }, 
         token));
      }
      try {
         Task.WaitAll(tasks.ToArray());
         Console.WriteLine("\nTotal random numbers generated: {0:N0}", totalCount);
         Console.WriteLine("Total sum of all random numbers: {0:N2}", totalValue);
         Console.WriteLine("Random number mean: {0:N4}", totalValue/totalCount);
      }
      catch (AggregateException e) {
         foreach (Exception inner in e.InnerExceptions) {
            TaskCanceledException canc = inner as TaskCanceledException;
            if (canc != null)
               Console.WriteLine("Task #{0} cancelled.", canc.Task.Id);
            else
               Console.WriteLine("Exception: {0}", inner.GetType().Name);
         }         
      }
      finally {
         source.Dispose();
      }
   }
}
// The example displays output like the following:
//       Task 1 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,502.47
//       Random number mean: 0.5003
//       
//       Task 0 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,445.63
//       Random number mean: 0.5002
//       
//       Task 2 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,556.04
//       Random number mean: 0.5003
//       
//       Task 3 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,178.87
//       Random number mean: 0.5001
//       
//       Task 4 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,819.17
//       Random number mean: 0.4999
//       
//       Task 5 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,190.58
//       Random number mean: 0.5001
//       
//       Task 6 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,720.21
//       Random number mean: 0.4999
//       
//       Task 7 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,000.96
//       Random number mean: 0.4995
//       
//       Task 8 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,499.33
//       Random number mean: 0.4997
//       
//       Task 9 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 1,000,193.25
//       Random number mean: 0.5001
//       
//       Task 10 finished execution.
//       Random numbers generated: 2,000,000
//       Sum of random numbers: 999,960.82
//       Random number mean: 0.5000
//       
//       
//       Total random numbers generated: 22,000,000
//       Total sum of all random numbers: 11,000,067.33
//       Random number mean: 0.5000

Es unterscheidet sich von der ersten Beispiel auf folgende Weise:

  • Die Variablen zum Nachverfolgen der Anzahl der Zufallszahlen generiert und die Summe in jeder Aufgabe befinden sich lokal auf den Task daher keine Notwendigkeit zum Verwenden besteht der ThreadStaticAttribute Attribut.

  • Die statische Task.WaitAll -Methode verwendet, um sicherzustellen, dass der Hauptthread nicht abgeschlossen, bevor alle Aufgaben beendet wurden. Besteht keine Notwendigkeit für das CountdownEvent Objekt.

  • Die Ausnahme, die aus den Aufgabenabbruch ergibt wird angegeben, der Task.WaitAll Methode. Im vorherigen Beispiel wird sie von jedem Thread behandelt.

Der Zufallszahlengenerator bietet Methoden, mit die Sie die folgenden Arten von Zufallszahlen generieren können:

  • Eine Reihe von Byte Werte. Sie bestimmen die Anzahl von Byte-Werten durch Übergeben eines Arrays initialisiert, um die Anzahl der Elemente, die Methode zum zurückgeben soll, die NextBytes Methode. Im folgenden Beispiel werden 20 Byte.

    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
    
  • Eine einzelne ganze Zahl. Sie können auswählen, ob Sie eine Ganzzahl zwischen 0 und einen maximalen Wert (Int32.MaxValue – 1) durch Aufrufen der Next() -Methode, eine ganze Zahl zwischen 0 und einen bestimmten Wert durch Aufrufen der Next(Int32) -Methode oder eine ganze Zahl innerhalb eines Bereichs von Werten durch Aufrufen der Next(Int32, Int32) Methode. In den parametrisierten Überladungen ist der angegebene maximale Wert exklusive. die tatsächliche Höchstzahl generiert ist eine kleiner als der angegebene Wert.

    Im folgenden Beispiel wird die Next(Int32, Int32) Methode, um zwischen-10 und 10 10 Zufallszahlen zu generieren. Beachten Sie, dass das zweite Argument für die Methode die exklusive obere Grenze des Bereichs von zufälligen Werten, die von der Methode zurückgegebenen angibt. Das heißt, die größte ganze Zahl, die die Methode zurückgeben kann, ist kleiner als dieser Wert.

    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
    
  • Ein einzelnes Gleitkommawert zwischen 0,0 und kleiner als 1,0 durch Aufrufen der NextDouble Methode. Die exklusive obere Grenze der Zufallszahl, die von der Methode zurückgegebenen ist 1, daher ist die tatsächliche Obergrenze 0.99999999999999978. Im folgende Beispiel werden 10 zufällige Gleitkommazahlen generiert.

    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
    
System_CAPS_importantWichtig

Die Next(Int32, Int32) Methode können Sie den Bereich der zurückgegebenen Zufallszahl an. Allerdings die maxValue -Parameter, der angibt, der obere Bereich zurückgegebene Zahl, eine exklusive, keine inklusive Wert ist. Dies bedeutet, dass den Methodenaufruf Next(0, 100) Gibt einen Wert zwischen 0 und 99 und nicht zwischen 0 und 100.

Können Sie auch die Random Klasse für Aufgaben wie das Generieren von System.Boolean Zufallswerte, Generieren von zufällige Gleitkommazahl Werte mit einem Bereich von 0 bis 1 außer, Generieren von zufälligen 64-Bit-Ganzzahlen, und nach dem Zufallsprinzip ein eindeutiges Element aus einem Array oder einer Auflistung abrufen. Diese und andere häufige Aufgaben finden Sie in der Verwendung System.Random,... Abschnitt.

Sie können Ihre eigenen Zufallszahlengenerator implementieren, durch Erben von der Random -Klasse und durch Angabe Ihrer zufälliger Algorithmus für die Erzeugung. Um einen eigenen Algorithmus angeben, müssen Sie überschreiben die Sample -Methode, die die zufälliger Algorithmus für die Erzeugung implementiert. Sie sollten auch überschreiben, die Next(), Next(Int32, Int32), und NextBytes Methoden, um sicherzustellen, dass sie die überschriebene Aufrufen Sample Methode. Sie müssen nicht außer Kraft setzen der Next(Int32) und NextDouble Methoden.

Ein Beispiel für die von abgeleitet ist die Random Klasse und ändert dessen Standardwert Pseudozufallszahlen, finden Sie unter der Sample -Referenzseite.

In den folgenden Abschnitten besprechen und Bereitstellen von Beispielcode für einige der Methoden, die Zufallszahlen in Ihrer app verwenden möchten.

Gelegentlich möchten Sie generieren dieselbe Sequenz von Zufallszahlen in Testszenarien und Spiele zu spielen. Testen mit derselben Sequenz von Zufallszahlen, können Sie erkennen von Regressionen und Fehlerkorrekturen zu bestätigen. Die gleiche Sequenz von Zufallszahl können Spiele Sie vorherige Spiele wiedergegeben.

Sie können die gleiche Sequenz von Zufallszahlen generieren, durch die Bereitstellung des gleichen Startwerts, der Random(Int32) Konstruktor. Der Ausgangswert bietet einen Startwert für den Algorithmus von Pseudozufallszahlen Generation. Im folgenden Beispiel wird 100100 als eine beliebige Startwert zum Instanziieren der Random -Objekt zeigt 20 zufällige Gleitkommawerte, und behält den Seed-Wert. Anschließend wird der Seed-Wert wiederhergestellt, instanziiert einen neuen Zufallszahlen-Generator, und zeigt die gleichen 20 zufällige Gleitkommawerte. Beachten Sie, dass im Beispiel verschiedene Sequenzen von Zufallszahlen erstellt werden kann, wenn in den verschiedenen Versionen von .NET Framework ausführen.

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

Bietet unterschiedliche Startwerte auf Instanzen der Random Klasse bewirkt, dass jede Zufallszahlen-Generator um eine andere Sequenz von Werten zu erzeugen. Sie können einem Ausgangswert angeben, entweder explizit durch Aufrufen der Random(Int32) -Konstruktor oder implizit durch Aufrufen der Random() Konstruktor. Die meisten Entwickler rufen den parameterlosen Konstruktor, der die Systemuhr verwendet. Im folgenden Beispiel wird dieser Ansatz zum Instanziieren zweier Random Instanzen. Jede Instanz wird eine Reihe von 10 zufällige ganze Zahlen.

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

Jedoch aufgrund der endliche Auflösung erkennt die Systemuhr Zeitdifferenz nicht, die weniger als etwa 15 Millisekunden. Daher, wenn der Code Ruft die Random() Überladung zum Instanziieren zweier Random Objekte nacheinander Sie versehentlich geleistet werden die Objekte mit identischen Startwerten. Um dies im vorherigen Beispiel zu sehen, kommentieren Sie die Thread.Sleep -Methodenaufruf, und kompilieren und führen Sie das Beispiel erneut.

Um dies zu verhindern, wird empfohlen, Sie ein einzelnes instanziieren Random -Objekt statt mehrerer. Da jedoch Random ist nicht threadsicher ist, müssen Sie ein Gerät für die Synchronisierung verwenden, wenn der Zugriff auf eine Random -Instanz durch mehrere Threads; Weitere Informationen finden Sie der Random-Klasse und Threadsicherheit weiter oben in diesem Thema. Alternativ können Sie einen verzögerungsmechanismus, wie z. B. die Sleep Methode, die im vorherigen Beispiel verwendet werden, um sicherzustellen, dass die Instanziierungen mehr als 15 Millisekunden voneinander auftreten.

Ganze Zahlen in einem angegebenen Bereich abrufen möchten, rufen Sie die Next(Int32, Int32) -Methode, die Angabe der niedrigere Wert und die Obergrenze für die Anzahl den Zufallszahlengenerator zurückgegeben werden sollen. Die Obergrenze ist eine exklusive, keine inklusive Wert. Es ist also in den Bereich der Werte, die von der Methode zurückgegebenen nicht enthalten. Im folgenden Beispiel wird diese Methode zum Generieren von Zufallszahlen zwischen-10 und 10. Beachten Sie, dass es 11 gibt, der größer als der Wert den gewünschten Wert für die maxValue Argument im Aufruf Methode.

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

Rufen Sie die Next(Int32, Int32) -Methode zum Abrufen von Zahlen mit einer angegebenen Anzahl von Ziffern. Zum Abrufen von Zahlen mit vier Ziffern (d. h. Zahlen, die im Bereich von 1000 bis 9999), rufen Sie z. B. die Next(Int32, Int32) -Methode mit einer minValue Wert 1000 und ein maxValue Wert 10.000, wie im folgenden Beispiel gezeigt.

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

Die NextDouble Methodenrückgabe zufällige Gleitkommawerte Bereich von 0 auf weniger als 1. Allerdings sollten Sie oft zufällige Werte in einem anderen Bereich zu generieren.

Wenn das Intervall zwischen der minimalen und maximalen Wert für den gewünschten 1 ist, können Sie den Unterschied zwischen das gewünschte Intervall für die Start- und 0 hinzufügen, auf die Anzahl von zurückgegebenen die NextDouble Methode. Im folgenden Beispiel wird diese Option, um 10 Zufallszahlen zwischen-1 und 0.

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

Zufällige Gleitkommazahlen generiert wird, dessen untere Grenze 0 jedoch Obergrenze ist größer als 1 (oder, bei negativen Zahlen, dessen untere Grenze ist kleiner als-1 und Obergrenze ist 0), die Grenze ungleich NULL Zufallszahl multiplizieren. Im folgenden Beispiel wird dies 20 Millionen zufällige Gleitkommazahlen generiert diesen Bereich von 0 bis Int64.MaxValue. In zeigt auch die Verteilung von Zufallswerten, die von der Methode generiert.

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 %

Um zufällige Gleitkommazahlen zwischen zwei beliebigen Werten zu generieren, wie die Next(Int32, Int32) Methode für ganze Zahlen enthält, verwenden Sie die folgende Formel:

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

Im folgenden Beispiel wird 1 Million Zufallszahlen, die im Bereich von 10.0 11.0 generiert, und zeigt die Verteilung.

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 %)

Die Random Klasse stellt Methoden zur Erstellung keinen Boolean Werte. Allerdings können Sie eine eigene Klasse oder Methode dafür definieren. Das folgende Beispiel definiert eine Klasse, BooleanGenerator, mit einer einzelnen Methode, NextBoolean. Die BooleanGenerator -Klasse speichert ein Random Objekt als eine private Variable. Die NextBoolean -Methode ruft die Random.Next(Int32, Int32) Methode und übergibt das Ergebnis an die Convert.ToBoolean(Int32) Methode. Beachten Sie, dass 2 als Argument an die obere Grenze der Zufallszahl verwendet wird. Da dies ein ausgeschlossener Wert ist, gibt der Methodenaufruf entweder 0 oder 1 zurück.

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 %)

Anstatt eine separate Klasse generiert zufällige Boolean Werte, die im Beispiel könnte einfach eine einzelne Methode definiert haben. In diesem Fall wird jedoch die Random Objekt sollte als eine Variable auf Klassenebene, um zu vermeiden, instanziieren ein neues definiert wurden Random Instanz in jedem Methodenaufruf. In Visual Basic kann die Random-Instanz als definiert eine statische in der Variablen der NextBoolean Methode. Das folgende Beispiel stellt eine Implementierung bereit.

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 %)

Die Überladungen der Next Methode 32-Bit-Ganzzahlen zurück. Allerdings kann in einigen Fällen mit 64-Bit-Ganzzahlen arbeiten möchten. Sie können dies wie folgt tun:

  1. Rufen Sie die NextDouble Methode zum Abrufen der Gleitkommazahl mit doppelter Genauigkeit Datenpunktwert.

  2. Multiplizieren Sie den Wert von Int64.MaxValue.

Im folgenden Beispiel verwendet dieses Verfahren zum Generieren von 20 Millionen zufälliger Ganzzahlen und kategorisiert sie in 10 gleich große Gruppen. Wertet dann die Verteilung der zufälligen Zahlen durch zählen der Anzahl in jeder Gruppe von 0 bis Int64.MaxValue. Wie die Ausgabe des Beispiels zeigt, werden die Zahlen über den Bereich einer langen ganzen Zahl mehr oder weniger gleichmäßig verteilt.

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 %

Ein alternatives Verfahren, dass Bitmanipulation verwendet keine echten Zufallszahlen generiert. Diese Methode ruft Next() zum Generieren von zwei ganzen Zahlen, links-verschiebt eine von 32 Bits und OR-Operatoren werden zusammen. Dieses Verfahren hat zwei Nachteile:

  1. Da Bit 31 das Vorzeichenbit ist, ist der Wert in Bit 31 der resultierende long integer-Wert immer 0. Dies kann durch Generieren einer zufälligen 0 oder 1, es links-Verschiebung 31 Bits und OR adressiert werden mit der ursprünglichen zufällige Ganzzahl.

  2. Ganz im ernst, da die Wahrscheinlichkeit, die der von Wert zurückgegebene Next() 0, kommt es wenige zufällige Zahlen im Bereich von 0 x 0 0x00000000FFFFFFFF.

Überladung von der Next -Methode können Sie den Bereich von Zufallszahlen an die NextBytes Methode nicht. Das folgende Beispiel implementiert eine NextBytes Methode, die den Bereich der zurückgegebenen Bytes angeben kann. Definiert eine Random2 von abgeleitete Klasse Random und überlädt die NextBytes Methode.

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

Die NextBytes(Byte[], Byte, Byte) Methode umschließt einen Aufruf an die Next(Int32, Int32) Methode und gibt den minimalen Wert und eine, die größer als der maximale Wert (in diesem Fall 0 und 101), dass wir das Byte-Array zurückgegeben werden sollen. Da wir sicher sind, dass die ganzzahligen Werte zurückgegebene die Next Methode werden innerhalb des Bereichs von den Byte Datentyp aufweisen, können wir sicher umgewandelt werden (in c#) oder konvertieren (in Visual Basic) von Ganzzahlen in Byte.

Zufallszahlen dienen häufig als Indizes zum Abrufen von Werten aus Arrays oder Auflistungen. Um einen zufälligen Indexwert abzurufen, rufen Sie die Next(Int32, Int32) -Methode, und verwenden, die die untere Grenze des Arrays als Wert für seine minValue Argument und größer als die obere Grenze des Arrays als Wert für seine maxValue Argument. Für ein nullbasiertes Array, dies entspricht der Length Eigenschaft oder größer als der Rückgabewert der Array.GetUpperBound Methode. Das folgende Beispiel ruft den Namen einer Stadt in den Vereinigten Staaten nach dem Zufallsprinzip aus einem Array von Städten.

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

Ein Zufallszahlen-Generator kann immer doppelte Werte zurückgeben. Der Zahlenbereich wird kleiner oder die Anzahl der generierten Werte größer wird, wächst die Wahrscheinlichkeit von Duplikaten. Wenn zufällige Werte eindeutig sein müssen, werden mehr Zahlen generiert, um Duplikate zu kompensieren zunehmend Leistung vermindert.

Es gibt eine Reihe von Techniken, um dieses Szenario zu behandeln. Häufig wird ein Array oder -Auflistung, die die Werte abgerufen werden sollen, sowie ein paralleles Array, das zufällige Gleitkommazahlen enthält. Das zweite Array wird mit Zufallszahlen aufgefüllt, die zum Zeitpunkt der erste Array erstellt, und die Array.Sort(Array, Array) -Methode verwendet, um das erste Array zu sortieren, unter Verwendung der Werte in den parallelen Arrays.

Z. B. Wenn Sie ein Solitärspiel entwickeln, möchten Sie sicherstellen, dass jede Karte nur einmal verwendet wird. Anstatt das Generieren von Zufallszahlen rufen Sie eine Karte und nachverfolgt, ob die Karte bereits behandelt wurde, können Sie ein paralleles Array von Zufallszahlen erstellen, die verwendet werden kann, um die Präsentation zu sortieren. Nach der Präsentation sortiert wird, kann Ihre app einen Zeiger an den Index des nächsten Karte auf den Stapel verwalten.

Dieser Ansatz wird anhand des folgenden Beispiels veranschaulicht. Definiert eine Card Klasse, stellt eine Spielkarte und einen Dealer -Klasse, die einem Kartenspiel falsch platzierte behandelt. Die Dealer Klassenkonstruktor füllt zwei Arrays: eine deck Arrays, bei dem Gültigkeitsbereich der Klasse, die alle Karten im Stapel, und eine lokale darstellt order Array, das die gleiche Anzahl von Elementen wie die deck array erstellt und nach dem Zufallsprinzip generiert Standardheaderdatei Double Werte. Die Array.Sort(Array, Array) Methode wird aufgerufen, um das Sortieren der deck Array basierend auf den Werten in der order Array.

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

Hinweise für Aufrufer:

Die Implementierung des Zufallszahlengenerators in die Random Klasse ist nicht unbedingt Hauptversionen von .NET Framework unverändert. Daher sollte nicht Sie davon ausgehen, dass der gleiche Ausgangswert in der gleichen pseudozufälligen Sequenz in verschiedenen Versionen von .NET Framework führt.

Hinweise für Vererber:

In .NET Framework 1.0 und 1.1, eine minimale Implementierung einer Klasse, die von abgeleitet Random erforderlich sind, überschreiben die Sample Methode, um einen neuen oder geänderten Algorithmus zum Generieren von Zufallszahlen zu definieren. Die abgeleitete Klasse könnten vertrauen, auf die Implementierung der Basisklasse von der Random.Next(), Random.Next(Int32), Random.Next(Int32, Int32), NextBytes, und NextDouble Methoden zur Implementierung der abgeleiteten Klasse Aufrufen der Sample Methode.

In .NET Framework 2.0 und höher, das Verhalten der Random.Next(), Random.Next(Int32, Int32), und NextBytes Methoden wurden geändert, damit nicht unbedingt die Implementierung der abgeleiteten Klasse von Aufrufen der Sample Methode. Daher abgeleitete Klassen Random die als Ziel .NET Framework 2.0 und höher müssen auch diese drei Methoden überschreiben.

Das folgende Beispiel erstellt ein einzelner Zufallszahlengenerator und ruft seine NextBytes, Next, und NextDouble Methoden zum Generieren von Sequenzen von Zufallszahlen in verschiedenen Bereichen.

using System;

public class Class1
{
   public static void Main()
   {
      // Instantiate random number generator using system-supplied value as seed.
      Random rand = new Random();
      // Generate and display 5 random byte (integer) values.
      byte[] bytes = new byte[4];
      rand.NextBytes(bytes);
      Console.WriteLine("Five random byte values:");
      foreach (byte byteValue in bytes)
         Console.Write("{0, 5}", byteValue);
      Console.WriteLine();   
      // Generate and display 5 random integers.
      Console.WriteLine("Five random integer values:");
      for (int ctr = 0; ctr <= 4; ctr++)
         Console.Write("{0,15:N0}", rand.Next());
      Console.WriteLine();
      // Generate and display 5 random integers between 0 and 100.//
      Console.WriteLine("Five random integers between 0 and 100:");
      for (int ctr = 0; ctr <= 4; ctr++)
         Console.Write("{0,8:N0}", rand.Next(101));
      Console.WriteLine();
      // Generate and display 5 random integers from 50 to 100.
      Console.WriteLine("Five random integers between 50 and 100:");
      for (int ctr = 0; ctr <= 4; ctr++)
         Console.Write("{0,8:N0}", rand.Next(50, 101));
      Console.WriteLine();
      // Generate and display 5 random floating point values from 0 to 1.
      Console.WriteLine("Five Doubles.");
      for (int ctr = 0; ctr <= 4; ctr++)
         Console.Write("{0,8:N3}", rand.NextDouble());
      Console.WriteLine();
      // Generate and display 5 random floating point values from 0 to 5.
      Console.WriteLine("Five Doubles between 0 and 5.");
      for (int ctr = 0; ctr <= 4; ctr++)
         Console.Write("{0,8:N3}", rand.NextDouble() * 5);
   }
}
// The example displays output like the following:
//    Five random byte values:
//      194  185  239   54  116
//    Five random integer values:
//        507,353,531  1,509,532,693  2,125,074,958  1,409,512,757    652,767,128
//    Five random integers between 0 and 100:
//          16      78      94      79      52
//    Five random integers between 50 and 100:
//          56      66      96      60      65
//    Five Doubles.
//       0.943   0.108   0.744   0.563   0.415
//    Five Doubles between 0 and 5.
//       2.934   3.130   0.292   1.432   4.369

Das folgende Beispiel generiert eine zufällige ganze Zahl, die als Index verwendet einen Zeichenfolgenwert aus einem Array abgerufen.

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

Universelle Windows-Plattform
Verfügbar seit 8
.NET Framework
Verfügbar seit 1.1
Portierbare Klassenbibliothek
Unterstützt in: portierbare .NET-Plattformen
Silverlight
Verfügbar seit 2.0
Windows Phone Silverlight
Verfügbar seit 7.0
Windows Phone
Verfügbar seit 8.1

Alle öffentlichen statischen Member ( Shared in Visual Basic) dieses Typs sind threadsicher. Die Threadsicherheit für Instanzmember ist nicht garantiert.

Zurück zum Anfang
Anzeigen: