So I'm a c# noob. I have a quick question that I can't find an answer to anywhere else.
[Serializable()]
public class Dictionary
{
private Random m_RandomGenerator = new Random();
public int GetNext()
{
return m_RandomGenerator.Next(100);
}
}
The Dictionary
instance is loaded each time the program starts, and this code will return the exact same sequence of numbers each time it is run. By which I mean, each time the executable is run. Surely the time value it's seeded with should be different (DateTime.Now.Ticks I assume?).
A couple of points:
Does anyone know why? I did double check that I'm not creating a new instance of Dictionary each time, so that's not the issue.
Well, colour me embarrassed. As it turns out the culprit was the [Serializable()] attribute. The dictionary class I was using was loaded from a previously exported file, which was obviously loading the seed back into Random(). Changing the variable to static meant that the seed value was no longer loaded from the previously serialised instance - hiding the issue.
Thanks to all the people offering constructive advice!
You can prevent member variables from being serialized by marking them with the NonSerialized attribute as follows. If possible, make an object that could contain security-sensitive data nonserializable. If the object must be serialized, apply the NonSerialized attribute to specific fields that store sensitive data.
The current implementation of the Random class is based on a modified version of Donald E. Knuth's subtractive random number generator algorithm. 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.
Seed Int32. A number used to calculate a starting value for the pseudo-random number sequence.
(CW because this is way too big for a comment)
This test will only ever repeat when Random is seeded. You should post the code calling Dictionary because there may be something fishy there (assuming the code posted is the actual code) or even better post your own test that reproduces the issue.
[Test]
public void TestDictionary()
{
var dictionary = new Dictionary();
for(int i = 0; i < 10; i++)
{
Console.WriteLine(dictionary.GetNext());
}
}
[Serializable] // added after the fact
public class Dictionary
{
//private Random m_RandomGenerator = new Random(12);
private Random m_RandomGenerator = new Random();
public int GetNext()
{
return m_RandomGenerator.Next(100);
}
}
This test does repeat your results but that's because of the answer here:
[Test]
public void TestDictionary2()
{
var alpha = new Dictionary();
var bravo = new Dictionary();
for(int i = 0; i < 10; i++)
{
Console.WriteLine("{0} - {1}", alpha.GetNext(), bravo.GetNext());
}
}
For completeness, here's a serialization test:
[Test]
public void SerializationPerhaps()
{
var charlie = new Dictionary();
Dictionary delta = null;
// Borrowed from MSDN: http://msdn.microsoft.com/en-us/library/system.serializableattribute.aspx
//Opens a file and serializes the object into it in binary format.
using (var stream = File.Open("data.xml", FileMode.Create))
{
var formatter = new BinaryFormatter();
formatter.Serialize(stream, charlie);
}
//Opens file "data.xml" and deserializes the object from it.
using (var stream = File.Open("data.xml", FileMode.Open))
{
var formatter = new BinaryFormatter();
delta = (Dictionary) formatter.Deserialize(stream);
stream.Close();
}
for(int i = 0; i < 10; i++)
{
Assert.AreEqual(charlie.GetNext(), delta.GetNext());
}
}
The source of your problem must be somwhere else than in the code you posted. Here is the same code, embedded in a test harness:
using System;
namespace RandomTest
{
public class Dictionary
{
private Random m_RandomGenerator = new Random();
public int GetNext()
{
return m_RandomGenerator.Next(100);
}
}
class Program
{
static void Main(string[] args)
{
Dictionary d = new Dictionary();
for (int i=0;i<10;i++)
{
int r = d.GetNext();
Console.Write("{0} ",r);
}
Console.WriteLine();
}
}
}
It returns a different sequence every time it is run.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With