c# 如何生成随机数

来源:这里教程网 时间:2026-02-21 17:39:52 作者:

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></random>
每线程隔离实例
改用
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(),大概率得到一串相同数字

种子逻辑本身不难,但错一次就可能让“随机”变成“固定”,尤其在分布式或高并发服务里,得盯紧实例生命周期和调用上下文。

相关推荐