IRONSOFTWAREHOME

Generowanie Losowych Liczb w C#

Generating Random Numbers in C#

Tim Corey

10m 05s

Generowanie losowych liczb w C# wydaje się powinno być jednowierszowe, i w wielu przypadkach tak jest. Jednak język oferuje więcej niż jeden sposób na generowanie losowych wartości, a różnice między nimi mają znaczenie, gdy uwzględniasz bezpieczeństwo wątków, odtwarzalność i przypadek użycia. Wybranie niewłaściwego podejścia może wprowadzić subtelne błędy w kodzie wielowątkowym lub uczynić zgłoszony defekt niemożliwym do odtworzenia.

W swoim filmie "Generating Random Numbers in C#", Tim Corey omawia klasyczna Random klase, wyjasnia, dlaczego wartosci seed istnieją, i wprowadza Random.Shared jako nowoczesny domyslny wybor. Omówimy każde podejście wraz z uzasadnieniem za nim, abyś mógł wybrać odpowiednie, nie zgadując. Jeśli kiedykolwiek zastanawiałeś się, dlaczego istnieje tyle dróg do czegoś, co wydaje się tak proste, ten artykuł wyjaśnia to.

Konfigurowanie Dema

[0:11 - 0:59] Tim pracuje w aplikacji konsolowej działającej na Visual Studio 2026 (obecnie w wersji podglądowej) z .NET 10. Zaznacza, że wszystko, co tu demonstruje, obejmuje równie dobrze .NET 9 i Visual Studio 2022, więc możesz podążać za tym z dowolnymi narzędziami, które już masz zainstalowane.

Uklad demonstracyjny to for petla, która drukuje dwie losowe wartosci obok siebie przy kazdej iteracji. Posiadanie dwóch wyników wykonujących się równolegle ułatwia obserwację, czy oba generatory działają niezależnie, czy też zwracają zgodne wyniki, rozróżnienie, które nabiera znaczenia, gdy pojawiają się wartości nasion.

Klasyczna Klasa Random

[0:59 - 3:28] Oryginalne podejscie do generowania losowych liczb calkowitych w C# polega na utworzeniu instancji klasy Random:

Random rng1 = new Random();
Random rng2 = new Random();
C#

Każda instancja utrzymuje swój własny wewnętrzny stan. Wywolanie .Next(1, 101) na dowolnej z nich zwraca liczba calkowita miedzy 1 a 100. Tim podkresla szczegól, który wprowadza nowicjuszy w blad: najmniejsza wartosc jest wlaczająca, ale maksymalna nie. Jesli chcesz wartosci od 1 do 100, przekaż 1 i 101, a nie 1 i 100.

int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);
C#

Uruchomienie aplikacji potwierdza, że obie instancje produkują różne sekwencje. Ten wynik wydaje się intuicyjny, ale co się stanie, gdy obie instancje dzielą ten sam punkt wyjścia, mówi zupełnie inna historia.

Jedno wazne zastrzezenie dotyczace tego podejscia: indywidualne instancje Random nie sa bezpieczne wątkowo. Jeśli Twoja aplikacja wykonuje przetwarzanie równoległe i wiele wątków uzyskuje dostęp do tej samej instancji, wewnętrzny stan może zostać uszkodzony, generując zera lub powtarzające się wartości. Bezpieczną praktyką jest utworzenie jednej instancji na wątek. To ograniczenie jest jednym z powodów, dla których język wprowadził później lepszą alternatywę.

Wartości Nasion i Odtwarzalne Sekwencje

[3:28 - 6:00] Następnie Tim podaje jawne nasienie do obu konstruktorów:

Random rng1 = new Random(25);
Random rng2 = new Random(25);
C#

Wynik zmienia się dramatycznie. Oba generatory teraz produkują identyczne sekwencje: 79, 16, 25, 90, 50, 41 i tak dalej. Liczby nadal są nieprzewidywalne indywidualnie, jeśli nie znasz nasienia, ale dany ten sam punkt wyjścia, progresja jest deterministyczna.

Czemu ktoś powinien tego chcieć? Tim daje praktyczny przykład. Wyobraź sobie grę, która generuje losowe zdarzenia w trakcie sesji. Gracz zgłasza błąd, ale odtworzenie go wydaje się niemożliwe, ponieważ wyniki były zrandomizowane. Jesli gra rejestruje seed uzyty w tej sesji, programista moze odtworzyc dokladny ciag decyzji, inicjalizując nową instancje Random z tą samą wartością. Ta sama logika dotyczy scenariuszy testów jednostkowych, gdzie potrzebujesz spójnych wyjść, aby napisać wiarygodne asercje przeciwko zrandomizowanemu zachowaniu.

Instancje z nasieniami dają kontrolowaną losowość: sekwencję wyglądającą nieprzewidywanie, ale mogącą być odtwarzaną na żądanie. Ta mozliwosc jest powodem, dlaczego klasyczny konstruktor Random akceptujący seed nie został wycofany, chociaz obecnie istnieje prostsze API.

Random.Shared: Nowoczesny Domyślny

[7:36 - 9:01] Począwszy od .NET 6, zalecane podejscie do wiekszosci generowania losowych liczb to Random.Shared:

int output1 = Random.Shared.Next(1, 101);
int output2 = Random.Shared.Next(1, 101);
C#

Nie jest wymagane tworzenie instancji. Random.Shared to statyczna, bezpieczna wątkowo instancja zarzadzana przez runtime. Wywolujesz .Next() (lub jakakolwiek z innych metod klasy Random) i otrzymujesz wartosc, nie martwąc się o czas życia obiektu czy współbieżność.

Tim uruchamia demo dwa razy, aby to udowodnić. Pierwsze wykonanie zaczyna się od 94 i 91; druga zaczyna się od 42 i 70. W odroznieniu od instancji z seedem, Random.Shared korzysta z innego stanu początkowego za każdym razem, gdy proces jest uruchamiany. Nie możesz ustawić nasienia, co oznacza, że nie możesz wygenerować odtwarzalnej sekwencji za pomocą tego API. To jest kompromis: prostota i bezpieczeństwo w zamian za rezygnację z deterministycznego odtworzenia.

Poza .Next(), Random.Shared udostepnia metody generowania floatów, wypelniania tablic bajtów i mieszania kolekcji. Dla zdecydowanej większości kodu aplikacji, gdzie potrzebujesz szybkiej losowej wartości bez ceremonii, ta pojedyncza statyczna właściwość zastępuje złożoność zarządzania własnymi instancjami.

Wybór Właściwego Podejścia

[9:01 - 9:30] Tim kończy zwięzłym frameworkiem decyzyjnym. Dla codziennej losowosci (wybieranie wartosci, mieszanie listy, wybieranie losowego elementu), Random.Shared jest odpowiednim wyborem. Nie wymaga żadnej konfiguracji, obsługuje współbieżność i działa poprawnie między wątkami.

Kiedy potrzebujesz powtarzalnej serii wyników, czy to do debugowania, testów, czy symulacji, utwórz dedykowaną instancję Random z znanym seedem. Pamiętaj, że te instancje nie są bezpieczne do współdzielenia między wątkami.

A dla wszystkiego, co wymaga bezpieczeństwa (tokeny, klucze, sole hasła), żadne z tych podejść nie jest odpowiednie. Tim kieruje widzów do kryptograficznych bibliotek w System.Security.Cryptography, które produkują wartości nie tylko losowe, ale także odporne na przewidywanie.

Podsumowanie: Proste API, Znaczące Różnice

[9:30 - 9:50] To co czyni ten temat mylnym to jak mało kodu potrzeba. Jedna linia może wygenerować losową liczbę za pomocą któregokolwiek z tych podejść. Kompleksowość nie tkwi w składni, ale w zrozumieniu, jakie gwarancje dostarcza każda metoda: bezpieczeństwo wątków, odtwarzalność czy siła kryptograficzna.

Wnioski

[9:50 - 10:05] Podsumowując: Random.Shared pokrywa wiekszość potrzeb bez konfiguracji i z wbudowaną bezpiecznością wątkową. Instancje Random z seedem pozwalają odtworzyć konkretną sekwencję, kiedy wymaga tego debugowanie lub testowanie. Generator kryptograficzny należy do kodu wrażliwego na bezpieczeństwo, w którym przewidywalność jest wrażliwością, a nie cechą.

Następnym razem, gdy sięgniesz po losową liczbę w C#, decyzja sprowadza się do jednego pytania: czy musisz później odtworzyć tę sekwencję? Jeśli odpowiedź brzmi nie, Random.Shared to wszystko, czego potrzebujesz.

Przykład wskazówki: Przy wywoływaniu Random.Shared.Next(min, max), zanotuj, że max jest wykluczający. Zakres od 1 do 100 wymaga przekazania 1 i 101. Ta niedokładność jednego dotyczy także instancji z nasieniem.

Obejrzyj pełny film na jego Kanale YouTube i zdobądź więcej wiedzy na temat podstaw C#.

Earn More by Sharing What You Love

Do you create content for developers working with .NET, C#, Java, Python, or Node.js? Turn your expertise into extra income!

Let's Stay in Touch!

Join our newsletter, you’ll get exclusive access on article updates. We value your privacy

Key in blue circle

Uzyskaj natychmiast swój darmowy 30-dniowy Klucz Testowy.

Your trial license will be sent to your email address

Brak ograniczeń. 100% dostępności. Bez karty kredytowej.

bullet_checkedNie wymaga karty kredytowej ani tworzenia kontaBrak ograniczeń. 100% dostępności. Bez karty kredytowej.
  • Logo Aetna
  • Logo NASA
  • Logo GE
  • Logo Porsche
  • Logo USDA
  • Logo Qatar
Join Millions of Engineers who’ve tried IronPDF
Otrzymaj swoją Konsultację Bez Zobowiązań
Wypełnij poniższy formularz lub wyślij e-mail na sales@ironsoftware.com
Twoje dane zawsze będą utrzymywane w tajemnicy.
Zaufane przez miliony inżynierów na całym świecie
Logotypy klientów Iron Software
Otrzymaj swój darmowy Klucz Próbny na 30 dni natychmiast.
Nie wymaga karty kredytowej ani tworzenia konta