C#'ta Rastgele Sayılar Üretmek
C#'ta rastgele sayılar üretmek, tek satırlık bir işlem gibi görünüyor ve çoğu durumda öyledir. Ancak dil, rastgele değerler üretmek için birden fazla yol sunar ve thread güvenliği, yeniden üretilebilirlik ve kullanım durumu dikkate alındığında, aralarındaki farklar önem kazanır. Yanlış yaklaşıma karar vermek, çoklu thread kodunda ince hataların oluşmasına neden olabilir veya bildirilen bir hatayı yeniden üretmeyi imkansız hale getirebilir.
Video "C#'de Rastgele Sayılar Üretme"da Tim Corey, klasik Random sınıfını anlatıyor, tohum değerlerinin neden var olduğunu açıklıyor ve Random.Shared'yi modern varsayılan olarak tanıtıyor. Her yaklaşımı, ardındaki mantıkla birlikte ele alacağız, böylece tahmin etmeden doğru olanı seçebilirsiniz. Eğer bu kadar basit bir şey için neden birden fazla yol olduğunu merak ettiyseniz, bu makale bunu ayrıntılarıyla ele alır.
Demo Kurulumu
[0:11 - 0:59] Tim, Visual Studio 2026'da (şu anda önizlemede) .NET 10'da çalışan bir konsol uygulaması içinde çalışmaktadır. Burada gösterilen her şeyin, halihazırda kurulu olan araçları kullanarak .NET 9'a ve Visual Studio 2022'ye de eşit ölçüde uygulandığını belirtiyor.
Demo düzeni, her yinelemede yan yana iki rastgele değer yazdıran bir for döngüsüdür. Paralel olarak çalışan iki çıktı, her iki üretecin de bağımsız çalışıp çalışmadığını veya eşleşen sonuçlar verip vermediğini gözlemlemeyi kolaylaştırır, bu ayrım, başlangıç değerleri konuya girdiğinde önemli hale gelir.
Klasik Random Sınıfı
[0:59 - 3:28] C#'de rastgele tamsayılar üretmek için orijinal yaklaşım, Random sınıfının bir örneğini oluşturmaktır:
Random rng1 = new Random();
Random rng2 = new Random();Random rng1 = new Random();
Random rng2 = new Random();Her örnek kendi iç durumunu korur. Bunlardan birine .Next(1, 101) çağrısı yapmak 1 ile 100 arasında bir tamsayı üretir. Tim, yeni başlayanları yanıltan bir ayrıntıya dikkat çekiyor: minimum değer dahil edilirken, maksimum değer dahil değildir. 1'den 100'e kadar değerler istiyorsanız, 1 ve 101 geçmelisiniz, 1 ve 100 değil.
int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);int output1 = rng1.Next(1, 101);
int output2 = rng2.Next(1, 101);Uygulamayı çalıştırmak, her iki örneğin de farklı diziler ürettiğini doğrular. Bu sonuç sezgisel gibi hissettirse de, her iki örneğin başlangıç noktasını paylaştıkları durumda farklı bir hikayeyi anlatır.
Bu yaklaşım hakkında önemli bir uyarı: bireysel Random örnekleri iş parçacığı açısından güvenli değildir. Uygulamanız paralel işlem gerçekleştirdiğinde ve aynı örneğe birden fazla thread eriştiğinde, içsel durum bozulabilir, sıfırlar veya tekrarlanan değerler üretebilir. Güvenli uygulama, her thread için bir örnek oluşturmaktır. Bu kısıtlama, dilin daha sonra daha iyi bir alternatif tanıtmasının nedenlerinden biridir.
Başlangıç Değerleri ve Tekrarlanabilir Diziler
[3:28 - 6:00] Tim daha sonra her iki yapıcıya da belirli bir başlangıç değeri geçirir:
Random rng1 = new Random(25);
Random rng2 = new Random(25);Random rng1 = new Random(25);
Random rng2 = new Random(25);Çıktı dramatik şekilde değişir. Her iki üreteç de artık aynı dizileri üretir: 79, 16, 25, 90, 50, 41, ve böyle devam eder. Başlangıç değerini bilmiyorsanız, sayılar hâlâ tek tek öngörülemez, ancak aynı başlangıç değeri verildiğinde, ilerleme deterministiktir.
Bunu neden birisi ister? Tim, pratik bir örnek verir. Bir oyunun bir oturum boyunca rastgele olaylar ürettiğini hayal edin. Bir oyuncu bir hata bildirir, ancak onu yeniden üretmek imkansız görünür çünkü sonuçlar rastgele seçilmiştir. O oturum için kullanılan tohum oyun tarafından kaydedildiyse, bir geliştirici aynı değeriyle yeni bir Random örneği başlatarak tam karar dizisini yeniden oluşturabilir. Birim testi senaryolarına aynı mantık uygulanır, burada rastgele davranışa karşı güvenilir teyitler yazmak için tutarlı çıktılar gerekir.
Başlangıç değerli örnekler, kontrol edilen rastgelelik sağlar: görünüşte öngörülemez ancak talep üzerine yeniden oynatılabilir bir dizi. Bu yetenek, tohum kabul eden klasik Random yapıcısının kaldırılmamış olmasının sebebidir, çünkü şimdi daha basit bir API mevcut.
Random.Shared: Modern Varsayılan
[7:36 - 9:01] .NET 6 ile başlayarak, en çok önerilen rasgele sayı üretim yaklaşımı Random.Shared'dir:
int output1 = Random.Shared.Next(1, 101);
int output2 = Random.Shared.Next(1, 101);int output1 = Random.Shared.Next(1, 101);
int output2 = Random.Shared.Next(1, 101);Burada örnekleme yoktur. Random.Shared, çalışma zamanı tarafından yönetilen statik, iş parçacığı açısından güvenli bir örnektir. .Next()'yi (ya da Random sınıfındaki diğer yöntemlerden birini) çağırırsınız ve obje ömrü veya eşzamanlılık ile ilgili endişe duymadan bir değer alırsınız.
Tim bu noktayı kanıtlamak için demoyu iki kez çalıştırır. İlk çalıştırma 94 ve 91 ile başlar; İkinci ise 42 ve 70 ile başlar. Tohumlanmış bir örnekten farklı olarak, Random.Shared her işlem başlatıldığında farklı bir başlangıç durumundan çeker. Bir başlangıç değeri ayarlayamazsınız, bu da bu API aracılığıyla tekrarlanabilir bir dizi üretemeyeceğiniz anlamına gelir. Bu da değiş tokuşun bir parçasıdır: belirgin tekrar oynatmadan vazgeçme karşılığında basitlik ve güvenlik.
.Next()'un ötesinde, Random.Shared double'lar üretmek, bayt dizilerini doldurmak ve koleksiyonları karıştırmak için yöntemler sağlar. Tören gereksinimi olmadan hızlı bir rastgele değere ihtiyaç duyduğunuz uygulama kodlarının çoğu için, bu tek statik özellik, kendi örneklerinizi yönetme zorunluluğunu ortadan kaldırır.
Doğru Yaklaşımı Seçmek
[9:01 - 9:30] Tim, karar verme çerçevesiyle kısaca kapanış yapar. Gündelik rastgelelik için (bir değer seçmek, bir listeyi karıştırmak, rastgele bir eleman seçmek), doğru çağrı Random.Shared'dir. Kurulum gerektirmez, eşzamanlılıkla başa çıkar ve thread'ler arasında doğru şekilde davranır.
Tekrarlanabilir bir çıktı serisi gerektiğinde, ister hata ayıklama, test etme veya simülasyon tekrarı için, bilinen bir tohum ile özel bir Random örneği oluşturun. Bu örneklerin thread'ler arasında paylaşılmasının güvenli olmadığını unutmayın.
Ve güvenlikle ilgili herhangi bir şey için (token, anahtar, parola soli), hiçbir yaklaşım uygun değildir. Tim, sadece rastgele değil aynı zamanda öngörülemeye karşı da dayanıklı değerler üreten kriptografik kütüphanelere System.Security.Cryptography içinde dikkat çekiyor.
Özet: Basit API, Anlamlı Farklar
[9:30 - 9:50] Bu konuyu yanıltıcı yapan şey, ne kadar az kod gerektirdiğidir. Bu yaklaşımlardan herhangi biriyle bir satır rastgele bir sayı üretebilir. Karmaşıklık, sözdiziminde değil, her yöntemin sağladığı garantileri anlamadadır: thread güvenliği, tekrarlanabilirlik veya kriptografi gücü.
Sonuç
[9:50 - 10:05] Özetlemek gerekirse: Random.Shared sıfır kurulum ile çoğu ihtiyacı karşılar ve yerleşik iş parçacığı güvenliği sunar. Tohumlanmış Random örnekleri, hata ayıklama veya test etme gerektirdiğinde belirli bir sırayı tekrar üretmenizi sağlar. Kriptografik üreteçler, predikton güvenliği değil, özelliği olduğu güvenlik duyarlı kodlarda yer alır.
C#'ta bir dahaki sefere rastgele bir sayı seçerken, karar bir soruya bağlı: Bu diziyi daha sonra yeniden oynatmanız gerekiyor mu? Cevap hayır ise, ihtiyacınız olan tek şey Random.Shared'dir.
Örnek İpucu: Random.Shared.Next(min, max) çağrısı yaparken, max'ın dahil olmadığını unutmayın. 1 ile 100 arası bir aralık, 1 ve 101 geçmeyi gerektirir. Bu kenar hatası, başlangıç değeri olan örnekler için de geçerlidir.
YouTube Kanalı üzerindeki tüm videoyu izleyin ve C# temelleri hakkında daha fazla bilgi edinin.

