This article is currently in the process of being translated into German (~99% done).
Randomness with the Random class
Manchmal benötigt man Zufälligkeit in seiner Applikation. Dies kann aus verschiedenen Gründen der Fall sein, möglicherweise möchte man die Einträge einer Liste zufällig vertauschen (wie beim Kartenmischen) oder vielleicht programmiert man ein Spiel und man möchte den Gegner in eine zufällige Richtung bewegen. Egal aus welchen Gründen man Zufallszahlen braucht, auf irgendeine Weise muss man diese vom Computer bekommen. Glücklicherweise kann c# uns dabei helfen.
In den meisten Fällen beginnt es mit der Random - Klasse, die es erlaubt, eine oder mehrere Zufallszahlen in einem bestimmten Bereich zu generieren. Es ist sogar ziemlich einfach zu verwenden:
Random random = new Random();
Console.WriteLine("A random number: " + random.Next());
Wir initialisieren einfach eine neue Instanz der Random-Klasse und dann rufen wir die Methode Next() auf um eine ganzzahlige Zufallszahl zu bekommen - sehr einfach!
Benötigt man anstelle einer Ganzzahl eine Dezimalzahl, kann man anstelle von Next() einfach die Methode NextDouble() verwenden, diese liefert eine Zahl zwischen 0.0 (einschließlich) and 0.99 (In Wirklichkeit alles kleiner als 1.0):
Random random = new Random();
Console.WriteLine("A random number with decimals: " + random.NextDouble());
Zufallszahlen in einem bestimmten Bereich
Meistens möchte man nicht einfach irgendeine Zufallszahl, man möchte sie innerhalb eines bestimmten Bereichs, beispielsweise zwischen 1 und 100. Keine Sorge, das kann die Random - Klasse ganz einfach erledigen:
Random random = new Random();
Console.WriteLine("A random number between 1 and 100: " + random.Next(1, 101));
Ich verändere einfach den Aufruf von Next() so, dass dieser ein Minimum und ein Maximum als Parameter übergeben bekommt. Beachte, dass zwar der untere Wert (das Minimum) Inklusiv ist, (dieser Wert kann also auch als möglicher Rückgabewert vorkommen), der obere Wert (das Maximum) ist hingegen Exklusiv (Dieser Wert kann also nicht als Rückgabewert zurückkommen). Aus diesem Grund wird im Beispiel der Wert 101 anstelle von 100 eingesetzt. Falls die Zahl zwischen 0 und 99 liegen soll, würde der Aufruf wie folgt aussehen:
Console.WriteLine("A random number between 0 and 99: " + random.Next(0, 100));
Einen Startwert (seed) festlegen
Die Random - Klasse wird immer mit einem Startwert (engl. seed = Same) instanziiert. Dies kann entweder direkt durch den Benutzer geschehen, indem ein solcher Wert übermittelt wird, oder automatisch (indirekt) durch das Framework. Dieser Startwert ermöglicht es im Wesentlichen, Kontrolle über die Zufälligkiet zu bekommen. Ein spezifischer Startwert, der mehrfach verwendet wird, erlaubt es, die selbe Zufallszahlenfolge mehrfach zu erzeugen. Das hört sich vielleicht erstmals etwas eigenartig an, aber für Testzwecke zu einer Applikation oder einem Spiel kann das sehr nützlich und sinnvoll sein.
Ein Startwert kann der Random-Klasse durch Verwendung des überladenen Konstruktors (d.h. Konstruktor mit der folgenden Signatur) - wie folgt - übergeben werden:
Random random = new Random(1000);
Sehen wir uns an, was geschieht, wenn wir das zur Erzeugung von 5 aufeinanderfolgenden Zufallszahlen verwenden:
Random random = new Random(1000);
for(int i = 0; i < 5; i++)
Console.WriteLine("A random number between 1 and 100: " + random.Next(1, 101));
Wie oft auch immer dieser Code durchlaufen wird, die 5 "zufälligen" Zahlen werden sicherlich so aussehen:
A random number between 1 and 100: 16
A random number between 1 and 100: 24
A random number between 1 and 100: 76
A random number between 1 and 100: 1
A random number between 1 and 100: 70
Man sieht also, dass die Zufallszahlen, die die Random - Klasse erzeugt, überhaupt nicht mehr zufällig sind. Es handelt sich also in Wirklichkeit um Pseudo-Zufallszahlen, wenn diese einen Startwert benützen. Daher wird das Framework einen Startwert erzeugen wenn beim Aufruf keiner übergeben wird. Im originalen .NET - Framework wurde die aktuelle Uhrzeit benutzt, wohingegen das moderne .NET core Framework den Thread - statischen (??) Pseudozufallszahlengenerator verwendet um den Startwert zu erzeugen. In anderen Worten, wenn kontrollierte Zufälligkeit (also Pseudozufälligkeit) nicht gebraucht wird, kann man sich - wie es in den ersten Beispielen gezeigt wurde - einfach auf den Default-Konstruktor stützen.
Zusammenfassung
Zur Erzeugung von Zufallszahlen wird die Random Klasse verwendet. Will man die Zahlen vorhersehbar "zufällig" haben, übergibt man einen Startwert (seed) mit Hilfe des überladenen Konstruktors. Will man (wirklich) zufällige Zufallszahlen, überlasst man die Generierung des Startwerts einfach dem Framework indem man den Standard-Konstruktor aufruft.
Nehmen Sie auch zur Kenntnis, dass das Instanziieren der Random-Klasse doch gewissermaßen teuer im Sinne von Ressourcenverbrauch ist. Daher sollte das Instanziieren nicht mehrfach - beispielsweise innerhalb einer Schleife - geschehen. Es sollte zu Beginn des Programms eine einzige Instanz der Random-Klasse erzeugt werden und die Next() - Methode (oder die entsprechenden anderen wie NextDouble()) so oft wie nötig aufgerufen werden.
Schließlich, wie bereits diskutiert, ist die Random - Klasse ein Pseudozufallszahlengenerator. Falls man - beispielsweise für kryptographische zwecke und / oder Erstellung von zufälligen Passwörtern - etwas sichereres haben möchte, kann man die Klasse RNGCryptoServiceProvider benützen.