C# ใช้ Class System.Random สำหรับ Pseudorandom Number Generation
การใช้งานพื้นฐาน
using System;
public class Program
{
public static void Main()
{
Random r = new Random();
// Random int: 0 ถึง Int32.MaxValue
int any = r.Next();
// Random int: 0 ถึง 99
int zeroTo99 = r.Next(100);
// Random int: 10 ถึง 49 (Inclusive start, Exclusive end)
int tenTo49 = r.Next(10, 50);
// Random double: 0.0 ถึง 1.0
double d = r.NextDouble();
// Random bytes
byte[] bytes = new byte[16];
r.NextBytes(bytes);
Console.WriteLine($"Any: {any}");
Console.WriteLine($"0-99: {zeroTo99}");
Console.WriteLine($"10-49: {tenTo49}");
Console.WriteLine($"Double: {d}");
}
}
⚠️ ปัญหา Thread Safety & Performance
Random ไม่ใช่ Thread-Safe การ Share Instance ระหว่าง Thread จะทำให้ผลลัพธ์แย่ (Contention, Correlation)
แนะนำ: ThreadLocal หรือ Random.Shared (.NET 6+)
.NET 6+ (Recommended):
// Shared Instance - Thread-Safe
int value = Random.Shared.Next(10, 50);
double d = Random.Shared.NextDouble();
// .NET Framework / .NET Core < 6:
private static readonly ThreadLocal _localRandom =
new ThreadLocal(() => new Random(Guid.NewGuid().GetHashCode()));
int value = _localRandom.Value.Next(10, 50);
Cryptographically Secure Random (Security Critical)
using System.Security.Cryptography;
// สำหรับ: Password, Token, Key, Salt, Nonce
using var rng = RandomNumberGenerator.Create();
byte[] bytes = new byte[32];
rng.GetBytes(bytes); // 256-bit Random
// Random Int Secure
byte[] intBytes = new byte[4];
rng.GetBytes(intBytes);
int secureInt = BitConverter.ToInt32(intBytes, 0) & 0x7FFFFFFF; // Positive Only
Seed Control (Reproducible Random)
// Same Seed = Same Sequence (Good for Testing/Debugging)
var r1 = new Random(12345);
var r2 = new Random(12345);
Console.WriteLine(r1.Next() == r2.Next()); // True
// Default Seed = Environment.TickCount (Time-based)
Random Extensions (Helper Methods)
public static class RandomExtensions
{
public static T NextEnum(this Random r) where T : Enum
{
var values = Enum.GetValues(typeof(T));
return (T)values.GetValue(r.Next(values.Length));
}
public static string NextString(this Random r, int length, string chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789")
{
return new string(Enumerable.Range(0, length).Select(_ => chars[r.Next(chars.Length)]).ToArray());
}
public static bool NextBool(this Random r, double probability = 0.5)
{
return r.NextDouble() < probability;
}
}
// ใช้งาน
var color = Random.Shared.NextEnum();
var token = Random.Shared.NextString(16);
var lucky = Random.Shared.NextBool(0.1); // 10% chance
สรุปเลือกใช้
| Use Case | Class/Method |
|---|---|
| General Purpose (Game, Sim, Test) | Random.Shared (.NET 6+) / ThreadLocal<Random> |
| Security (Password, Token, Crypto) | RandomNumberGenerator |
| Reproducible (Unit Test, Debug) | new Random(seed) |
| Parallel/High Throughput | ThreadLocal<Random> หรือ Random.Shared |