我有8个标签。我希望每个标签的text属性设置为随机数。由于某种原因,只有第一个标签有一个数字集,为什么会这样? (另外,虽然没有直接相关,如果有更好的方法做label1.Text,label2.Text,label3.Text等,请告诉我!)
由于
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
go();
}
void go()
{
int[] numbers = new int[8];
foreach (int number in numbers)
{
numbers[number] = getRandomNumber();
}
label1.Text = numbers[0].ToString();
label2.Text = numbers[1].ToString();
label3.Text = numbers[2].ToString();
label4.Text = numbers[3].ToString();
label5.Text = numbers[4].ToString();
label6.Text = numbers[5].ToString();
label7.Text = numbers[6].ToString();
label8.Text = numbers[7].ToString();
}
int getRandomNumber()
{
Random random = new Random();
return random.Next(10, 1000);
}
}
答案 0 :(得分:6)
修改:更多问题
只有第一个标签有一个数字集
这样做的原因是你以这种方式声明了int[]
:{/ p>
int[] numbers = new int[8];
在此之后你有一个Length
8的数组,但是所有的整数都是default(int)
0是什么。
因此,以下foreach
循环...
foreach (int number in numbers)
{
numbers[number] = getRandomNumber();
}
...只会将第一个int
初始化为一个随机数(好吧,不是真正随机的,稍后会详细介绍)。您可以改为使用for
- 循环:
for (int iii=0; iii<numbers.Length;iii++)
{
numbers[iii] = getRandomNumber();
}
但如果您使用我下面的改进代码,也可以解决此问题。
在循环中使用相同的随机实例。否则它将创建相同的数字,因为它以当前时间播种。
MSDN:
随机数生成从种子值开始。如果相同 种子重复使用,生成相同系列的数字。一 产生不同序列的方法是制作种子价值 与时间有关,从而与每个新系列产生不同的系列 随机的实例。默认情况下,无参数构造函数 随机类使用系统时钟生成其种子值,而 它的参数化构造函数可以取基于的Int32值 当前时间的刻度数。
Random rnd = new Random();
foreach (int number in numbers)
{
numbers[number] = rnd.Next(10, 1000);
}
根据您的第二个问题如何改进代码:您可以使用带有标签的数组:
Random random = new Random();
var labels = new[] { label1, label2, label3, label4, label5, label6, label7, label8 };
for (int i = 0; i < labels.Length; i++)
{
labels[i].Text = random.Next(10, 1000).ToString();
}
答案 1 :(得分:5)
问题出在你的foreach
循环中。您正在使用number
作为索引,而它实际上是数组中索引处的值。结果是只有第一个label.Text
才有价值!此外,由于您每次都在创建新的Random
,Random.Next
将返回相同的值,因为随机种子基于时间。试试这个:
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
go();
}
void go()
{
int[] numbers = new int[8];
Random random = new Random();
for (int i = 0; i < 8; i++)
{
numbers[i] = random.Next(10, 1000);
}
label1.Text = numbers[0].ToString();
label2.Text = numbers[1].ToString();
label3.Text = numbers[2].ToString();
label4.Text = numbers[3].ToString();
label5.Text = numbers[4].ToString();
label6.Text = numbers[5].ToString();
label7.Text = numbers[6].ToString();
label8.Text = numbers[7].ToString();
}
}
答案 2 :(得分:1)
这是因为
int getRandomNumber()
{
Random random = new Random(); // <-- This line
return random.Next(10, 1000);
}
请改为:
private static readonly Random random = new Random(); // <-- only set once
int getRandomNumber()
{
return random.Next(10, 1000);
}
第一个发生的事情是,你一遍又一遍地用相同的值播种它,因为如果循环太紧,技术上没有时间。在第二个我正在做的是播种一次发电机 - 每次都得到一个不同的数字。
答案 3 :(得分:0)
正如 ShadowCat7 所指出的,这里的核心问题不是Random
被滥用,而是foreach
循环被滥用。
以下代码行。
int[] numbers = new int[8];
声明一个8 int
的数组,其值均为0
。
因此,当您执行以下foreach
循环时。
foreach (int number in numbers)
{
numbers[number] = getRandomNumber();
}
您正在遍历名为int
的整数数组中包含的每个numbers
值,如前所述,这些值都是0
!因此,当您将它用作数组索引operator []中的参数时,您将反复进行此调用。
numbers[0] = getRandomNumber();
这就是为什么你没有看到你的数组的其余部分填充了10到1000之间的伪随机数的真正原因。
虽然确实不断创建Random
的新实例会通过重复使用相同的种子一次又一次地为您生成相同的数字(在类似的循环中违背使用Random
的目的这个),这8个标签中有7个是0
的主要问题是由于foreach
循环的误用。
至于为每个Text
设置Label
值的聪明方法,请参阅 Tim Schmelter 的答案,因为它很棒。