c#表格:我在哪里放置我的随机数发生器?

时间:2010-10-03 19:06:39

标签: c# forms random

我试图在Windows窗体应用程序中使用随机数生成器,但我无法确定放置它的位置。我被告知“把它放在表单构造函数中”但我不认为我们说的是同一种语言。这是我试图找到一个家的代码:

Random rnd = new Random();
int guessMe = rnd.Next(0,100);

但每当我尝试将其置于click even方法之外时,它会说:

  

字段初始值设定项无法引用   非静态字段,方法或   物业'LAB6B.Form1.r'

所以我认为这意味着它听起来像;它必须在静态方法中。但是表单构造函数似乎也没有任何静态方法。有人可以折腾我吗?


以下是Form1.cs中的代码。我现在在线阅读其他一些教程,就是说要在Form1_Load事件中做随机数生成器,但是我从按钮点击事件中得到了一个上下文/范围错误。

    using System;
    using System.Collections.Generic;
    using System.ComponentModel;
    using System.Data;
    using System.Drawing;
    using System.Linq;
    using System.Text;
    using System.Windows.Forms;

    namespace LAB6B
    {

        public partial class Form1 : Form
        {


            public Form1()
            {
                InitializeComponent();            

            }

            private void Form1_Load(object sender, EventArgs e)
            {
                Random rnd = new Random();
                int guessMe = rnd.Next(0, 100);
            }

            private void btnEvaluate_Click(object sender, EventArgs e)
            {            
                int totGuesses = 0, myGuess;

                if (txtGuess.Text != "")
                {
                    myGuess = int.Parse(txtGuess.Text);
                    totGuesses++;
                    if (myGuess < guessMe)
                    {
                        btnEvaluate.Visible = false;
                        lblResult.Text = "Too Low!!";
                        lblResult.Visible = true;
                        BackColor = Color.SeaGreen;
                    }
                }

            }
        }
    }

1 个答案:

答案 0 :(得分:3)

如果你得到了这个建议,有人可能会建议你声明一个实例变量,但是在你的构造函数中初始化它。例如:

public class Foo
{
    private readonly Random rnd;

    public Foo()
    {
        rnd = new Random();
        // Other construction code
    }
}

然后,您可以在班级的任何地方使用rnd

这实际上大致相当于:

public class Foo
{
    private readonly Random rnd = new Random();

    public Foo()
    {
        // Other construction code
    }
}

...我最喜欢,因为它表明rnd的初始化与任何构造函数参数无关。

由于您的部分困难似乎是guessMe变量,因此这是一个更完整的版本:

public class Foo
{
    private readonly Random rnd = new Random();
    private int guessMe;

    public Foo()
    {
        guessMe = rng.Next(0, 100);
    }
}

这假设您需要guessMe作为实例变量,因此您可以在整个班级中引用它。另一方面,也许您不需要Random变量作为实例变量 - 如果您只生成一个随机数,那么它会更好:

public class Foo
{
    private readonly int guessMe;

    public Foo()
    {
        Random rnd = new Random();
        guessMe = rnd.Next(0, 100);
    }
}

但是,我个人不会使用这两种方法。我将使用一种技术,为每个线程创建一个Random实例,以避免Random的非线程安全风险,以及创建两个Random实例的危险彼此非常接近,并以相同的种子结束。

我在article on my site中已经相当广泛地写了这个,包括这个类:

using System;
using System.Threading;

public static class RandomProvider
{    
    private static int seed = Environment.TickCount;

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

    public static Random GetThreadRandom()
    {
        return randomWrapper.Value;
    }
}

您可以直接使用RandomProvider(每次需要生成随机数时调用GetThreadRandom),也可以将RandomProvider.GetThreadRandom作为参数的构造函数参数传递给您的类键入Func<Random> - 即注入“我希望能够随时获取Random实例”的依赖项。