c#写的代码,同样的代码用来随机生成数学题,为什么用Winform时候出来的内容都是重复的,用控制带程序就正常了?
版本是VS2022 .net6.0
winform一开始代码没有分到class里,我一开始是以为没有new一下不行,所以单独提出来了,控制台代码是直接复制过去的
这个是Winform代码:
```c#
public partial class frmText : Form
{
public frmText()
{
InitializeComponent();
}
//30个10以内加减法
private void button1_Click(object sender, EventArgs e)
{
Random r = new Random();
string ret = "";
for (int i = 0; i < 30; i++)
{
生成 a = new 生成();
ret += a.生成2();
ret += "\r\n";
}
textBox1.Text = ret;
}
}
public class 生成
{
Random r = new Random();
public string 生成2()
{
Random r = new Random();
return r.Next(0, 10) > 5 ? 生成一个加法() : 生成一个减法();
}
string 生成一个加法()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x + y <= 15)
{
return (x.ToString() + " + " + y.ToString());
}
else
{
return 生成一个加法();
}
}
string 生成一个减法()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x - y > 0)
{
return (x.ToString() + " - " + y.ToString());
}
else
{
return 生成一个减法();
}
}
}
这个是控制台代码:
```c#
for (int i = 0; i < 64; i++)
{
生成 s = new 生成();
Console.WriteLine(s.生成2());
}
Console.WriteLine();
public class 生成
{
Random r = new Random();
public string 生成2()
{
Random r = new Random();
return r.Next(0, 10) > 5 ? 生成一个加法() : 生成一个减法();
}
string 生成一个加法()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x + y <= 15)
{
return (x.ToString() + " + " + y.ToString() + " =");
}
else
{
return 生成一个加法();
}
}
string 生成一个减法()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x - y > 0)
{
return (x.ToString() + " - " + y.ToString() + " =");
}
else
{
return 生成一个减法();
}
}
}
Random r = new Random();
要定义成全局变量,你放按钮里每次生成一个新的,那随机出来的数也是一样的
每生成一个数都new random方法的话,生成间隔太短会生成同一个数,但用同一个random生成多次,就会是随机的
原因貌似是因为在生成类构造函数中,每次创建生成对象时都会创建一个Random类的新实例。 这会导致生成内容的重复,因为 Random 类的种子值是基于当前系统时间的,如果两个 Random 实例的创建时间太接近,它们可能会以相同的种子值结束并产生 相同的随机数序列。
在控制台代码中,生成 对象是在循环中创建的,每次创建之间有一段时间,允许 Random 的每个实例具有不同的种子值并产生不同的随机数序列。
然而,在 Winform 代码中,生成对象是在 for 循环中快速连续创建的,这意味着 Random 的每个实例可能具有相同的种子值并产生相同的随机数序列。
为避免此问题,您应该在类级别而不是在生成类构造函数中创建 Random 的单个实例,并在整个生成类中使用该实例。 这将确保生成的每个实例都使用相同的 Random 实例并避免重复问题。
像这样:
public class gen
{
private static Random r = new Random();
public string gen2()
{
return r.Next(0, 10) > 5 ? genadd() : genless();
}
string genadd()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x + y <= 15)
{
return (x.ToString() + " + " + y.ToString());
}
else
{
return genadd();
}
}
string genless()
{
int x = r.Next(0, 9);
int y = r.Next(0, 9);
if (x - y > 0)
{
return (x.ToString() + " - " + y.ToString());
}
else
{
return genless();
}
}
}