我有以下功能:

//Function to get random number
public static int RandomNumber(int min, int max)
{
    Random random = new Random();
    return random.Next(min, max);
}

我怎么称呼它:

byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
    mac[x] = (byte)(Misc.RandomNumber((int)0xFFFF, (int)0xFFFFFF) % 256);

如果我在运行时使用调试器单步执行该循环,我会得到不同的值(这是我想要的)。然而,如果我在代码下面两行放置断点,则mac数组的所有成员都具有相等的值。

为什么会这样?


当前回答

总是得到一个正随机数。

 var nexnumber = Guid.NewGuid().GetHashCode();
        if (nexnumber < 0)
        {
            nexnumber *= -1;
        }

其他回答

我使用Rnd()函数解决了这个问题:

Function RollD6() As UInteger
        RollD6 = (Math.Floor(6 * Rnd())) + 1
        Return RollD6
End Function

当表单加载时,我使用Randomize()方法确保每次运行都不会得到相同的随机数序列。

我宁愿使用以下类生成随机数:

byte[] random;
System.Security.Cryptography.RNGCryptoServiceProvider prov = new System.Security.Cryptography.RNGCryptoServiceProvider();
prov.GetBytes(random);

从.NET 6开始,Random类现在配备了一个名为Shared的静态属性:

提供可从任何线程并发使用的线程安全随机实例。

你可以这样使用:

// Function to get random number
public static int RandomNumber(int min, int max)
{
    return Random.Shared.Next(min, max);
}

访问线程安全对象的开销很小,因此如果您计划在单个线程上尽可能快地生成数百万个随机数,最好创建一个专用的random实例,而不是依赖Shared。

为什么会这样?

正如前面所回答的,每次调用new Random()时,都会得到用相同时钟初始化的Random类的新副本(因此它返回相同的值)。

现在,从.NET6开始,有一个易于使用且线程安全的替代方案:Random.Shared

在您的示例中,您可以删除所有函数RandomNumber,然后使用以下代码(使用相同的逻辑,但现在它工作正常):

byte[] mac = new byte[6];
for (int x = 0; x < 6; ++x)
    mac[x] = (byte)(Random.Shared.Next(0, 255));

为了在整个应用程序中易于重用,静态类可能会有所帮助。

public static class StaticRandom
{
    private static int seed;

    private static ThreadLocal<Random> threadLocal = new ThreadLocal<Random>
        (() => new Random(Interlocked.Increment(ref seed)));

    static StaticRandom()
    {
        seed = Environment.TickCount;
    }

    public static Random Instance { get { return threadLocal.Value; } }
}

然后可以使用静态随机实例,代码如下

StaticRandom.Instance.Next(1, 100);