Which is better and is there a difference in the random results ?
void Func1(Random rand)
{
var num=rand.Next();
}
void Func2(ref Random rand)
{
var num=rand.Next();
}
They are functionally equivalent. You don't update the rand reference in the function so passing it by ref does nothing.
Rule of thumb: don't use ref unless you absolutely have to and understand what it does.
1) Never use ref if you don't need it explicitely.
2) Usually you shouldn't need to pass Random through methods. If you have to, probably you are doing something wrong in your code.
Why? Because to be sure of a true randomness, it's better to always use the same Random instance instead of creating many of them.
That's why you should always declare one and use it around, like in this example:
class Program
{
static void Main(string[] args)
{
RandomNumbersPrinter randomNumbersPrinter = new RandomNumbersPrinter();
int randomInteger = randomNumbersPrinter.GetRandomInteger();
Console.WriteLine(randomInteger);
}
}
public class RandomNumbersPrinter
{
private static readonly Random _random = new Random();
public int GetRandomInteger()
{
return _random.Next();
}
}
Since Random is a reference type, the only difference is that the reference to the instance get copied when calling Func1.
In Func2, you are passing the actual existing reference to the Random itself to the method.
Please consult the docs for more information about this.
The bottom line is that you shouldn't use the ref keyword here unless you intend to assign rand to a new Random object in the method.
Related
Which is better to achieve efficiency if i need to use this object in many methods in my class?
Doing this:
Create object above of class so i can accecc c in multiple methods.
using System;
class Program
{
static Customers c = new Customers("text1", "text2");
public static void Main()
{
}
}
Or doing this:
Create object inside methods so every time i need to use c object i
must create it.
using System;
class Program
{
public static void Main()
{
Customers c = new Customers("text1", "text2");
}
}
Generally it is a best practice to restrict variables' scope(s) as much as possible (great explaination why). This means that if you need a variable to be accessible by multiple methods, then great, make a global variable. If not, then make it local because that's all it needs to be. Neither of these are "more efficient" than the other per-say, they are just used in different scenarios.
For example, let's say you're writing a simple calculator-like program to add/subtract 2
random numbers.
static int num1;
static int num2;
static void Main(string[] args){
var rand = new Random();
num1 = rand.Next(10); // Generate random number between 0 and 10
num2 = rand.Next(10);
Add();
Subtract();
Console.ReadLine();
}
static void Add(){
Console.WriteLine($"{num1} + {num2} = {num1+num2}");
}
static void Subtract(){
Console.WriteLine($"{num1} - {num2} = {num1-num2}");
}
In this example, num1 and num2 need to be processed by the Add() and Subtract() methods, so we make them global variables. The rand variable on the other hand is only needed in the Main() method, so we keep it local.
Global variables can also be accessed from within other classes (depending on their scope), whereas local variables cannot.
i have a listBox and i want everytime show random item from my list.
var random = new Random();
int index = random.Next(listBox1.Items.Count);
Console.Writeline(listBox1.Items[index].toString());
var random = new Random();
int index = random.Next(0, listBox1.Items.Count);
Console.Writeline(listBox1.Items[index].toString());
var random=new Random();
int index=random.Next(0,listBox1.Items.Count);
Basically random.Next(min,max) require min and max values so that random number is generated between the given range.
You should provide range also .
Console.Writeline(listBox1.Items[index].toString());
I just use your code #ilyas it's working fine, stick with it, just use
MessageBox.Show(listBox1.Items[index].ToString());
instead of
Console.Writeline(listBox1.Items[index].toString());
i assume you are creating WinForm Application
Your code seems to be ok. But if you are using it in a tight loop, it would give you always the same number. Maybe this is your problem?
Every time you do new Random() it is initialized using the clock.
This means that in a tight loop you get the same value lots of times. You should keep a single Random instance and keep using Next on the same instance.
//Define your random class with a static field
public static class RandomAccessor {
// Static field for your Random to create one instance only
private static readonly Random random = new Random();
// Object to lock sync on
private static readonly object syncLock = new object();
// Method to generate random number
public static int RandomNumber(int max)
{
lock(syncLock) {
// returns a random non-negative number less that max
return random.Next(max);
}
}
}
Then use it in your code like this:
int index = RandomAccessor.RandomNumber(listBox1.Items.Count);
Console.Writeline(listBox1.Items[index].toString());
Ask if you have any questions.
Here is a basic example how it will work.
using System;
using System.Windows.Forms;
namespace SimpleFormsApplication
{
public partial class Form1 : Form
{
private readonly Random _random = new Random();
public Form1()
{
InitializeComponent();
}
private void button_random_Click(object sender, EventArgs e)
{
int randomIndex = _random.Next(listBox1.Items.Count);
var randomItem = listBox1.Items[randomIndex];
MessageBox.Show($"Random item at index {randomIndex} is {randomItem}");
}
}
}
Please also have a look in here https://msdn.microsoft.com/en-us/library/system.random(v=vs.100).aspx and exermine the examples there.
I'm new to programming and have therefore a rather simple question.
I guess it should be possible to show two different pictures 50 times. Let’s say two different colored circles, in an random order for a second or until the user presses a certain key, but I have no idea how to start. Is there an easy way?
Maybe it's easier to start with a list of actions (either showing circle a or showing circle b) and randomly choosing one of it like the following modified code from a different question:
class Program
{
static void Main(string[] args)
{
List<Action> actions = new List<Action>();
actions.Add(() => Program.circleA());
actions.Add(() => Program.circleB());
Random random = new Random();
int selectedAction = random.Next(0, actions.Count()); // What does this line do?
actions[selectedAction].Invoke(); // And this one?
}
Afterwards I have to define what Program.circleA and Program.circleB does, right?
Should I implement this in a loop? If yes, how do I specify that each circle has to be shown 50 times before the breakout criteria is met?
I've search the Internet for similar problems, but I couldn't find a solution or maybe just couldn't understand them, so that's why I'm asking you guys and girls :)
If I understood your question correctly, your question is basically "How can I call a random action/method?" and "Is my logic of doing that okay?".
Starting with the second one (because it's easier), the answer will be the same as the answer to this simple question: "Is it doing its job?". Meaning if your logic is behaving like you wanted to, the answer is yes. If it doesn't, then no.
With the first one... It's a bit trickier because you can have many different solutions. You can use Reflection, Action, Func, custom delegates ...
(IMHO) So the "easy" way (if you have sh.. ton of methods) would be to use reflection and custom attributes, like so:
public class RandomCircleMethodAttribute : Attribute
{
public RandomCircleMethodAttribute() : base() { }
}
And then assign this Attribute to methods you want to call. Then using reflection, just get MethodInfo pointing to these methods and call them like so:
public class RandomCircleMethods
{
[RandomCircleMethod]
public void circleA() { //.. your logic here
}
[RandomCircleMethod]
public void circleB() { //.. your logic here
}
// add as many as you want
}
Then inside your EntryPoint ( Main(string[] args) ) :
List<MethodInfo> methods = typeof(RandomCircleMethods).GetMethods().Where(method => Attribute.IsDefined(method, typeof(RandomCircleMethod))).ToList();
int selectedAction = new Random().Next(0, methods.Count);
methods[selectedAction].Invoke(new RandomCircleMethods(), null);
This way you don't have to create list of Action. But this is as good as your current way of making the job done.
I would stick to your current logic though, because it's less confusing than using reflection.
So I am trying to learn some C#, currently on a short course on An Introduction to Programming. I have a question in my text book which is giving me pretty much simular results to this post Same random numbers from instantiated class
I have tried to follow the solution but get the same results every time, the task is to Roll two dice and display their numbers using 2 instances of a class. But like the post above the "dice" role the same number. If I call the same instance of the class twice and out put the values to separate labels I get completely different values like i want. here is the class:
namespace CH10_Ex10._5
{
public class ThrowDice
{
public ThrowDice()
{
}
private Random newRandom = new Random();
private int x;
public void Throw()
{
x = newRandom.Next(1, 7);
}
public int value
{
get
{
return x;
}
}
}
}
and here is my main form:
namespace CH10_Ex10._5
{
public partial class Form1 : Form
{
ThrowDice Die1;
ThrowDice Die2;
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice();
Die2 = new ThrowDice();
}
private void button1_Click(object sender, EventArgs e)
{
Die1.Throw();
dieOneLabel.Text = Convert.ToString(Die1.value);
Die2.Throw();
dieTwoLabel.Text = Convert.ToString(Die2.value);
}
}
}
I have tried to find an answer with out opening a new post so i am sorry if this have been answered before. I am very green at this.
My understanding is that if i declare objects with new, then i am creating separate instances of the class and therefore when i call those objects they should run independently/separately, but use the same rules which are specified in my class. I have tried to debug and as i step through the code i see the 2 separate calls to the class and what it looks like is the call 1 generates a random number eg 6 and call 2 seems to generate 6 as well.
thanks in advance
The problem is that the random instance will be initialized with the current time since you're using the default constructor. Since that happens on two instances very quick they get the same seed here:
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice();
Die2 = new ThrowDice();
}
You could make it static:
private static Random newRandom = new Random();
Random constructor:
The default seed value is derived from the system clock and has finite
resolution. As a result, different Random objects that are created in
close succession by a call to the default constructor will have
identical default seed values and, therefore, will produce identical
sets of random numbers.
However, Random is not thread safe. So you should have a look at this answer.
This is also really worth reading: C# in Depth: Random numbers which suggests to use ThreadLocal<T> which is new in .NET 4 instead of static with lock.
You can fix this using same random instance in both instances.For example you can add a constructor like this:
private Random newRandom;
public ThrowDice(Random rnd)
{
newRandom = rnd;
x = newRandom.Next(1, 7);
}
Then:
Random rnd = new Random;
public Form1()
{
InitializeComponent();
Die1 = new ThrowDice(rnd);
Die2 = new ThrowDice(rnd);
}
What i usually use :
private Random newRandom = new Random(Guid.NewGuid().GetHashCode());
I want the "BombenGenerieren(anzahlMinen)" only one time, how should I write it, that it doesn't generates new bombs every round?
public Game(int anzahlMinen, int xeingabe, int yeingabe)
{
_minenArray = new int[5, 5];
_emptyArray = new int[5, 5];
_boolArray = new bool[5, 5];
program = new Program();
zeichnen = new Draw();
BombenGenerieren(anzahlMinen);
FillPlayMap();
Umdreher(yeingabe, xeingabe);
zeichnen.OpenField(_minenArray, _boolArray);
//SeenMap();
}
I'm assuming Game is a constructor and you want to execute BombenGenerieren once and share it between instances.
What you should do, is make BombenGenerieren static and store whatever the effect of BombenGenerieren is in one or more static fields or properties. You should then call Game.BombenGenerieren before instantiating new Game objects, or alternatively create a static constructor as follows:
public static Game()
{
BombenGenerieren(anzahlMinen);
}
The static constructor will be executed the first time you use the Game type. Note that it does no take parameters, so anzahlMinen will have to be a constant. If that is a problem, go with the regular static method.
Another alternative is to encapsulate the result of the BombenGenerieren method in an object and pass that to the Game constructor, whcih can apply the result to each new class.
Basically, utilize a boolean variable to keep track of the execution of BombenGenerieren.
boolean bombenGeneriert = false;
public Game(int anzahlMinen, int xeingabe, int yeingabe) {
//...
BombenGenerieren(anzahlMinen);
//...
}
public void BombenGenerieren(int minen) {
if (!bombenGeneriert) {
bombenGeneriert = true;
//the rest of your code in this method
}
}
This will set bombenGeneriert to true the first the method is executed. Now on every execution it checks for !bombenGeneriert which will evaluate to false.
Besides, you should consider rearranging your code. I suspect you call Game() more than once, so you should probably relocate your BombenGenerieren() method, somewhere outside Game().
If Game is your class and Game() a constructor, than bombenGeneriert hast to be static:
static boolean bombenGeneriert = false;