所以我正在尝试学习一些C#,目前是关于编程简介的短期课程。我的教科书中有一个问题,这个问题给了我非常类似的结果Same random numbers from instantiated class
我试图按照解决方案但每次都获得相同的结果,任务是滚动两个骰子并使用2个类的实例显示它们的数字。但就像上面的帖子“骰子”角色一样。如果我两次调用同一个类的实例并将值放到单独的标签中,我会得到完全不同的值,就像我想要的那样。这是班级:
namespace CH10_Ex10._5
{
public class ThrowDice
{
public ThrowDice()
{
}
private Random newRandom = new Random();
private int x;
public void Throw()
{
x = newRandom.Next(1, 7);
}
public int value
{
get
{
return x;
}
}
}
}
这是我的主要形式:
namespace CH10_Ex10._5
{
public partial class Form1 : Form
{
ThrowDice Die1;
ThrowDice Die2;
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice();
Die2 = new ThrowDice();
}
private void button1_Click(object sender, EventArgs e)
{
Die1.Throw();
dieOneLabel.Text = Convert.ToString(Die1.value);
Die2.Throw();
dieTwoLabel.Text = Convert.ToString(Die2.value);
}
}
}
我试图找到答案而不打开新帖子,所以如果以前已经回答过,我很抱歉。我非常环保。
我的理解是,如果我使用new声明对象,那么我正在创建该类的单独实例,因此当我调用这些对象时,它们应该独立/单独运行,但使用我的类中指定的相同规则。我试图调试,当我逐步调试代码时,我看到对类的2个单独调用,它看起来是调用1生成一个随机数,例如6,调用2似乎也生成6。
提前致谢
答案 0 :(得分:3)
问题是随机实例将使用当前时间进行初始化,因为您使用的是默认构造函数。由于这种情况很快发生在两个实例上,因此它们会在这里得到相同的种子:
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice();
Die2 = new ThrowDice();
}
你可以把它变成静态的:
private static Random newRandom = new Random();
默认种子值来自系统时钟并具有有限性 解析度。结果,创建了不同的随机对象 通过调用默认构造函数来关闭连续 相同的默认种子值,因此,将产生相同的 随机数集。
但是,Random
不是线程安全的。所以你应该看看this answer.
这也非常值得一读:C# in Depth: Random numbers建议使用{4}}这是.NET 4中的新功能,而不是带有锁定的static
。
答案 1 :(得分:1)
您可以在两个实例中使用相同的随机实例来解决此问题。例如,您可以添加如下构造函数:
private Random newRandom;
public ThrowDice(Random rnd)
{
newRandom = rnd;
x = newRandom.Next(1, 7);
}
然后:
Random rnd = new Random;
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice(rnd);
Die2 = new ThrowDice(rnd);
}
答案 2 :(得分:-1)
我通常使用的是:
private Random newRandom = new Random(Guid.NewGuid().GetHashCode());