【问题标题】:Labels text values not setting标签文本值未设置
【发布时间】:2013-08-06 22:09:50
【问题描述】:

我有 8 个标签。我希望每个标签都将其文本属性设置为随机数。出于某种原因,只有第一个标签设置了数字,这是为什么呢? (另外,虽然没有直接关系,但如果有更好的方法来处理 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);
    }
}

【问题讨论】:

  • 在你的函数之外随机静态化。
  • 您的问题是为所有 8 个标签生成相同的数字?还是只有第一个标签显示一个值,而所有其他 7 个不显示任何数字?
  • @AustinSalonen 这不是重复的。正如在答案中发现的那样,Random 对象并不是问题的全部原因。所有其他标签仍被分配 0,主要问题是 foreach 循环。

标签: c#


【解决方案1】:

编辑:更多问题

只有第一个标签设置了数字

原因是你已经通过这种方式声明并初始化了int[]

int[] numbers = new int[8];

在这之后你有一个数组,Length 8 但所有整数都是default(int) 什么是 0。

因此下面的foreach循环...

foreach (int number in numbers) 
{
    numbers[number] = getRandomNumber();
}

... 只会将第一个 int 初始化为一个随机数(嗯,不是真的随机,稍后会详细介绍)。您可以改用for-loop:

for (int iii=0; iii<numbers.Length;iii++)
{ 
    numbers[iii] = getRandomNumber();
}

但是如果你使用我下面的改进代码也可以解决这个问题。


在循环中使用相同的随机实例。否则它将创建与当前时间相同的数字。

MSDN:

随机数生成从种子值开始。如果一样 种子重复使用,生成同一系列数字。一 产生不同序列的方法是使种子值 时间相关,从而产生不同的系列与每个新的 随机的实例。默认情况下,无参数构造函数 Random 类使用系统时钟生成其种子值,而 它的参数化构造函数可以采用一个 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();
}

【讨论】:

  • 感谢您的回答!作为新手,您介意我问为什么使用“var”数据类型吗?这像一个隐式声明吗?如果标签是一个对象,做一个对象数组不是更好吗?
  • @JoelKidd: var 不是真正的数据类型。它是实际类型的替代品。所以它仍然是强类型的(相对于dynamic),但它比Label[] 短。因此,如果类型很明显,因为我进行了分配,我使用var,只是为了防止水平滚动并且不要重复自己。如果类型不明显,我不使用var,而是使用实际类型,因为可读性比简洁更重要。但是,在这种情况下,最好使用Label[] ;-)
  • 非常感谢您的详细解释。我通常在编写 JavaScript,所以你可以理解这种困惑,所有的强类型对我来说都是新的,所以我想我最好问一下:P
  • @Tim 问题不在于标签文本不是随机的。他还没有走到那一步。除了空白之外,他没有得到任何文本。在您的第一个解决方案中,numbers[number] 是导致他遇到问题的原因。
  • @ShadowCat7 + Derek:你是对的。感谢您的注意。我已经相应地编辑了我的答案。
【解决方案2】:

问题出在您的foreach 循环中。您使用number 作为索引,而它实际上是数组中索引处的值。效果是只有第一个label.Text会有值!此外,由于您每次都创建一个新的RandomRandom.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();
    }
}

【讨论】:

    【解决方案3】:

    因为

    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);
    }
    

    第一个中发生的情况是,您一遍又一遍地用相同的值播种它,因为如果循环太紧,从技术上讲时间还没有滴答作响。在第二个中,我正在做的是给生成器播种一次 - 因此每次都会得到不同的数字。

    【讨论】:

      【解决方案4】:

      正如ShadowCat7所指出的,这里的核心问题不是Random被滥用,而是foreach循环被滥用。

      以下代码行。

      int[] numbers = new int[8];
      

      声明一个包含 8 个 int 的数组,所有的值都是 0

      因此,当您执行以下foreach 循环时。

      foreach (int number in numbers) 
      {
          numbers[number] = getRandomNumber();
      }
      

      您正在遍历名为numbers 的整数数组中包含的每个int 值,如前所述,它们都是0!因此,当您将它用作数组索引运算符 [] 中的参数时,您会重复进行此调用。

      numbers[0] = getRandomNumber();
      

      这就是为什么您没有看到数组的其余部分填充了 10 到 1000 之间的伪随机数的真正原因。

      虽然不断创建Random 的新实例确实会通过重复使用相同的种子来一遍又一遍地为您生成相同的数字(违背了在这样的循环中使用Random 的目的),但为什么 8 个标签中有 7 个是 0 的主要问题是因为滥用了 foreach 循环。

      至于为每个 Label 设置 Text 值的巧妙方法,请参阅 Tim Schmelter 的回答,因为它非常棒。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2014-02-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-17
        • 1970-01-01
        相关资源
        最近更新 更多