c#forms:我应该把随机数生成器放在哪里?
我曾试图在windows窗体应用程序中使用随机数生成器,但我无法确定将其放置在何处。我被告知“把它放在表单构造函数中”,但我认为我们说的不是同一种语言。以下是我试图为其找到一个家的代码:c#forms:我应该把随机数生成器放在哪里?,c#,forms,random,C#,Forms,Random,我曾试图在windows窗体应用程序中使用随机数生成器,但我无法确定将其放置在何处。我被告知“把它放在表单构造函数中”,但我认为我们说的不是同一种语言。以下是我试图为其找到一个家的代码: Random rnd = new Random(); int guessMe = rnd.Next(0,100); 但是,每当我尝试将其放置在click-even方法之外时,它都会说: 字段初始值设定项无法引用 非静态字段、方法或 属性“LAB6B.Form1.r” 所以我假设这意味着它听起来像什么;它必须位
Random rnd = new Random();
int guessMe = rnd.Next(0,100);
但是,每当我尝试将其放置在click-even方法之外时,它都会说:
字段初始值设定项无法引用
非静态字段、方法或
属性“LAB6B.Form1.r”
所以我假设这意味着它听起来像什么;它必须位于静态方法内部。但是表单构造函数似乎也没有任何静态方法。有人能扔我一根骨头吗
以下是Form1.cs中的代码。我现在正在网上阅读一些其他教程,其中说在Form1_加载事件中执行随机数生成器,但是我从button click事件中得到一个上下文/范围错误
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;
}
}
}
}
}
使用系统;
使用System.Collections.Generic;
使用系统组件模型;
使用系统数据;
使用系统图;
使用System.Linq;
使用系统文本;
使用System.Windows.Forms;
名称空间LAB6B
{
公共部分类Form1:Form
{
公共表格1()
{
初始化组件();
}
私有void Form1\u加载(对象发送方、事件参数e)
{
随机rnd=新随机();
int guessMe=rnd.Next(01100);
}
私有void btnEvaluate_单击(对象发送者,事件参数e)
{
int totGuess=0,myGuess;
如果(txtGuess.Text!=“”)
{
myGuess=int.Parse(txtGuess.Text);
totGuesses++;
如果(myGuess
如果您得到了这个建议,可能有人建议您声明一个实例变量,但在构造函数中初始化它。例如:
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
实例在时间上非常接近,并以相同的种子结束的危险
我在一篇文章中对此进行了相当广泛的论述,包括本课程:
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;
}
}
使用系统;
使用系统线程;
公共静态类随机提供程序
{
私有静态int seed=Environment.TickCount;
私有静态线程本地随机包装器=
新线程本地(()=>
新随机(联锁增量(参考种子))
);
公共静态随机GetThreadRandom()
{
返回randomWrapper.Value;
}
}
您可以直接使用
RandomProvider
(每次需要生成随机数时调用GetThreadRandom
),也可以将RandomProvider.GetThreadRandom
作为Func
类型参数的构造函数参数传递到类中,即插入“我希望能够随时获取Random
的实例“我真的很欣赏这个细节。这对我来说仍然不起作用,但我认为你比我的技能和我想要完成的范围要高一点,哈哈。这是一个创建数字猜测游戏的课堂作业。所以我使用C#net生成的表单和代码,基本文件设置;Form1.cs、Form1.Designer.cs和Program.cs我不确定在哪里让随机数生成器工作。这是一个复杂的部分类?我有范围问题。@Sin美学:不,这不应该是片面的——但当你没有提供太多的上下文时,很难说什么是错的。如果您发布一个简短但完整的程序来演示问题,我们可以更清楚地解释问题。(虽然我今晚不太可能再发帖了。)好的,我根据你告诉我的内容算出了。public分部类Form1:Form{public static readonly Random rnd=new Random();int guessMe=rnd.Next(0100);这最终消除了在静态方法之外无法访问的错误。一切看起来都很好,变量现在是全局的:)谢谢!@Sinaesync:不,这不是一个好方法。保存随机实例的静态变量是一个坏主意。将rnd
作为实例变量,但将guessMe
在方法或构造函数中初始化。我用一些示例编辑了我的答案。从中,似乎@JonSkeet自己已经放弃了在多线程上下文中使用线程Random
s的想法,而是主张使用单个Random
实例,并由调用方获取锁。