最常用方式是复用同一Random实例,避免循环中重复创建;多线程应使用Random.Shared(.NET 6+)或ThreadLocal;安全场景必须用RandomNumberGenerator。

用 Random 类生成基本随机数
最常用也最直接的方式是实例化 Random 类,然后调用它的方法。注意:不要在循环里反复新建 Random 实例,否则可能因种子相同导致重复序列。
推荐做法是复用同一个实例,尤其在高频调用场景下:
var rand = new Random(); int num = rand.Next(); // 0 到 int.MaxValue 之间 int range = rand.Next(1, 101); // 1 到 100(不含 101) double d = rand.NextDouble(); // [0.0, 1.0)
Random 在多线程下不安全
Random 实例不是线程安全的。多个线程同时调用 Next() 可能抛出 InvalidOperationException 或返回异常值(如负数、超限值)。
解决方案有三种,按推荐顺序:
- 用
ThreadLocal每线程隔离实例 - 改用
Random.Shared(.NET 6+,静态、线程安全) - 加锁(性能差,仅临时应急)
.NET 6 起推荐写法:
int safeNum = Random.Shared.Next(1, 101);
需要密码学安全?别用 Random
Random 和 Random.Shared 都是伪随机,可预测,**绝不能用于生成 Token、加密密钥、验证码盐值等安全敏感场景**。
应改用 System.Security.Cryptography.RandomNumberGenerator:
var bytes = new byte[4]; RandomNumberGenerator.Fill(bytes); int cryptoRand = BitConverter.ToInt32(bytes) & 0x7FFFFFFF;
这个值不可预测,但开销比 Random 高一个数量级,只在真正需要时用。
常见陷阱和兼容性注意
容易被忽略的点:
-
Next(min, max)的max是**排他上限**,比如Next(0, 5)只返回 0–4 - .NET Framework 与 .NET Core/.NET 5+ 的
Random算法不同,同一种子产生的序列不一致 - 给
Random传固定种子(如new Random(42))适合测试,但线上必须省略参数或用系统时间 - Unity 中若在
Update()里每帧 new Random(),大概率得到一串相同数字
种子逻辑本身不难,但错一次就可能让“随机”变成“固定”,尤其在分布式或高并发服务里,得盯紧实例生命周期和调用上下文。










