I was trying to use a random number generator in a windows forms app, but I’m having trouble figuring out where to put it. I’m being told “place it in the form constructor” but I don’t think we’re talking the same language. Here’s the code im trying to find a home for:
Random rnd = new Random();
int guessMe = rnd.Next(0,100);
But whenever I try to place it outside of the click even method, it says:
A field initializer cannot reference
the non-static field, method, or
property ‘LAB6B.Form1.r’
So i’m assuming that means what it sounds like; it has to be inside of a static method. But the form constructor doesn’t seem to have any static methods either. Can someone toss me a bone?
Here is the code from the the Form1.cs. Im reading some other tutorial online right now that is saying to do the random number generator in the Form1_Load event, but I’m getting a context/scope error from the button click event.
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;
}
}
}
}
}
If you’ve been given that advice, someone is probably suggesting that you declare an instance variable, but initialize it in your constructor. For example:
Then you can use
rndanywhere in your class.This is actually mostly equivalent to:
… which I mostly prefer, as it shows that the initialization of
rndhas nothing to do with any constructor parameters.As it seems that part of your difficulty is with the
guessMevariable, here’s a more complete version:This is assuming you need
guessMeto be an instance variable so you can refer to it throughout the class. On the other hand, perhaps you don’t need theRandomvariable to be an instance variable – if you’re only generating one random number, it would be better as:However, personally I wouldn’t use either of these approaches. I would use a technique which creates a single instance of
Randomper thread, to avoid both the perils ofRandombeing non-thread-safe, and the perils of creating two instances ofRandomvery close to each other in time, and ending up with the same seeds.I’ve written about this reasonably extensively in an article on my site, including this class:
You can either use
RandomProviderdirectly (callingGetThreadRandomevery time you need to generate a random number) or you can passRandomProvider.GetThreadRandominto your class as a constructor argument for a parameter of typeFunc<Random>– i.e. inject a dependency of “I want to be able to get an instance ofRandomat any time”.