C#'ta Rastgele Sayılar Üretme
C#'ta rastgele sayı üretmek tek satırlık bir işlemdir gibi görünse de, çoğu durumda da öyledir. Ancak dil, rastgele değer üretmek için birden fazla yol sunar ve bunlar arasındaki farkların önemi, iş parçacığı güvenliği, tekrarlanabilirlik ve kullanım durumu faktörlerine bağlandığında belirginleşir. Yanlış yaklaşım seçmek, çoklu iş parçacıklı kodda gizli hatalar oluşturabilir veya bildirilen bir hatanın yeniden üretilmesini imkansız hale getirebilir.
Tim Corey, "C# ile Rastgele Sayılar Oluşturma" başlıklı videosunda, klasik Random sınıfını detaylandırıyor, neden tohum değerlerinin var olduğunu açıklıyor ve modern varsayılan olarak Random.Shared sınıfını tanıtıyor. Her yaklaşımı ve bunların arkasındaki nedenleri ele alacağız, böylece doğru olanı tahmin etmeden seçebilirsiniz. Bir şeyin neden bu kadar basit birden fazla yolunun olduğuna dair hiç merak ettiyseniz, bu makale bunu açıklıyor.
Demo Kurulumu
[0:11 - 0:59] Tim, .NET 10 ile Visual Studio 2026 (şu anda önizleme aşamasında) üzerinde çalışan bir konsol uygulaması içinde çalışıyor. Burada gösterilen her şeyin .NET 9 ve Visual Studio 2022'ye eşit olarak uygulandığını belirtiyor, böylece zaten yüklü olan araçlarla takip edebilirsiniz.
Demo düzeni, her yinelemede yan yana iki rastgele değer yazdıran bir for döngüsüdür. Yan yana görünen iki çıktı, her iki üreteçin bağımsız mı davrandığını yoksa eşleşen sonuçlar mı ürettiğini gözlemlemeyi kolaylaştırıyor; bu fark, tohum değerleri işin içine girdiğinde önem kazanıyor.
Klasik Rastgele Sınıf
[0:59 - 3:28] C#'de rastgele tam sayılar oluşturmanın özgün 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. Her iki durumda da .Next(1, 101) çağrısı, 1 ile 100 arasında bir tam sayı üretir. Tim, yeni başlayanları yanıltan bir detayı vurgular: minimum değer dahildir, ancak maksimum değer değildir. 1'den 100'e kadar değerler istiyorsanız, 1 ve 101 geçirirsiniz, 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 farklı diziler ürettiğini doğrular. Bu sonuç sezgisel görünüyor; ancak her iki örnek aynı başlangıç noktasını paylaştığında tablo değişir.
Bu yaklaşım hakkında önemli bir uyarı: bireysel Random örnekleri iplik güvenli değildir. Uygulamanız paralel işlem gerçekleştiriyorsa ve birden fazla iş parçacığı aynı örneğe erişiyorsa, iç durum bozulabilir, sıfır veya tekrar eden değerler üretebilir. Güvenli uygulama, her iş parçacığı için bir örnek oluşturmaktır. Bu kısıtlama dilin daha sonra daha iyi bir alternatifi tanıtmasının nedenlerinden biridir.
Tohum Değerleri ve Tekrarlanabilir Sıralar
[3:28 - 6:00] Tim daha sonra her iki kurucuya açık bir tohum geçirir:
Random rng1 = new Random(25);
Random rng2 = new Random(25);Random rng1 = new Random(25);
Random rng2 = new Random(25);Çıktı dramatik bir şekilde değişir. Her iki jeneratör şimdi 79, 16, 25, 90, 50, 41, vb. gibi aynı dizileri üretir. Tohumu bilmiyorsanız, sayılar hâlâ bireysel olarak tahmin edilemezdir, ancak aynı başlangıç değerine dayandığında, ilerleme belirleyicidir.
Neden biri bunu ister? Tim pratik bir örnek veriyor. Bir oyun seansı boyunca rastgele olaylar üreten bir oyun hayal edin. Bir oyuncu bir hatayı bildiriyor, ancak bunu yeniden üretmek olanaksız görünüyor çünkü sonuçlar rastgeleydi. O oturum için kullanılan tohumu oyun günlüğüne kaydederse, bir geliştirici aynı değeri kullanarak yeni bir Random örneği başlatarak karar zincirini tam olarak yeniden oluşturabilir. Aynı mantık, birim testleri senaryolarına da uygulanır, burada rastlantısal davranışlara karşı güvenilir doğrulamalar yazmak için tutarlı çıktılar gerekir.
Tohum eklenmiş örnekler size kontrol edilebilir rastlantısallık sağlar: tahmin edilemez gibi görünen ancak talep üzerine yeniden oynatılabilir bir dizi. Bu yetenek, seed kabul eden klasik Random yapıcısının basitleştirilmiş bir API artık mevcut olmasına rağmen devre dışı bırakılmamış olmasının nedenidir.
Random.Shared: Modern Varsayılan
[7:36 - 9:01] .NET 6 ile başlayarak, çoğu rastgele sayı üretimi için önerilen yaklaşım Random.Shared'dır:
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);Hiçbir örnekleştirme söz konusu değildir. Random.Shared, çalışma zamanı tarafından yönetilen statik, iplik güvenli bir örnektir. .Next() (veya Random sınıfındaki diğer metotlar) üzerinden bir çağrı yaparsınız ve nesne yaşam süresi veya eşzamanlılıktan endişe etmeden bir değer alırsınız.
Tim, konuyu kanıtlamak için demoyu iki kez çalıştırıyor. İlk çalıştırma 94 ve 91 ile başlar; İkincisi 42 ve 70 ile başlar. Seedli bir örnekten farklı olarak, her işlem başlatıldığında Random.Shared farklı bir başlangıç durumundan başlar. Bir tohum ayarlayamazsınız, bu da bu API aracılığıyla tekrarlanabilir bir dizi üretemeyeceğiniz anlamına gelir. Bu, sadelik ve güvenlik karşılığında belirlenebilir tekrardan vazgeçmenin bedelidir.
.Next() dışında, Random.Shared çiftler oluşturma, bayt dizilerini doldurma ve koleksiyonları karıştırma metotları sunar. Tören olmaksızın hızlı bir rastgele değer ihtiyaç duyduğunuz çoğu uygulama kodu için, bu tek statik özellik, kendi örneklerinizi yönetmenin tekrarlayan kullanımını değiştirir.
Doğru Yaklaşımı Seçme
[9:01 - 9:30] Tim, kısa bir karar çerçevesiyle kapanışı yapıyor. Günlük rastgelelik (bir değer seçmek, bir listeyi karıştırmak, rasgele bir eleman seçmek) için, Random.Shared doğru çağrıdır. Herhangi bir kurulum gerektirmez, eşzamanlılığı ele alır ve iş parçacıkları arasında doğru davranır.
Hata ayıklama, test etme veya simülasyon tekrarı için tekrarlanabilir bir çıktı serisine ihtiyaçınız olduğunda, bilinen bir seed ile özel bir Random örneği oluşturun. Unutmayın, bu örnekler iş parçacıkları arasında paylaşılmak için güvenli değildir.
Ve güvenlik ile ilgili herhangi bir şey için (jetonlar, anahtarlar, parola tuzları), hiçbir yaklaşım uygun değildir. Tim izleyicileri sadece rastgele değil aynı zamanda tahmin edilmeye dirençli değerler üreten System.Security.Cryptography kriptografik kütüphanelerine yönlendirir.
Sonuç: Basit API, Anlamlı Farklar
[9:30 - 9:50] Bu konuyu aldatıcı yapan şey, ne kadar az kod gerektirdiğidir. Tek bir satır, bu yaklaşımlar aracılığıyla bir rastgele sayı üretebilir. Karmaşıklık sözdiziminde değil, her yönteminin sağladığı garantileri anlamaktadır: iş parçacığı güvenliği, tekrarlanabilirlik veya kriptografik güç.
Sonuç
[9:50 - 10:05] Özetlemek gerekirse: Random.Shared, sıfır kurulumu ve yerleşik iplik güvenliği ile çoğu ihtiyaçı karşılar. Seedli Random örnekleri, hata ayıklama veya test ihtiyaçı gerektirdiğinde belirli bir diziyi yeniden oluşturmanızı sağlar. Kriptografik jeneratörler, öngörülebilirliğin bir özellik değil, bir zafiyet olduğu güvenlik duyarlı kodlara aittir.
Bir dahaki sefere C#'ta rastgele bir sayı kullandığınızda, karar şu tek soruya bağlıdır: bu diziyi daha sonra yeniden oluşturmanız gerekecek mi? Cevap hayırsa Random.Shared ihtiyacınız olan her şeydir.
Örnek İpucu: Random.Shared.Next(min, max) çağrılırken, max'in dahil olmadığını unutmayın. 1 ile 100 arasında bir aralık, 1 ve 101 geçmeyi gerektirir. Bu bir-dışında sınır, tohum eklenmiş örneklere de uygulanır.
video'yu YouTube Kanalı'nda izleyin ve C# temelleri hakkında daha fazla içgörü kazanın.

