Hi,
The problem is arising because the "Random" class is being instantiated everytime the foo() method is called. And, as mentioned below, becuase the code is running so fast the default seed used (current datetime) is the same. To get round this, simply use a ** static ** "Random" object. There will be only one instance of it and you can quite happily keep calling Next() to generate a new unique random number... Lee -- http://www.secretorange.co.uk -----Original Message----- From: [email protected] on behalf of Cerebrus Sent: Mon 22/06/2009 11:21 To: DotNetDevelopment, VB.NET, C# .NET, ADO.NET, ASP.NET, XML, XML Web Services,.NET Remoting Subject: [DotNetDevelopment] Re: intefrace Your code functions correctly. The only problem arises from the fact that the Random object does not generate truly random numbers (It's a pseudo-random generator). However, the Random class allows you to generate sufficiently random sequences for this purpose by providing a unique seed value. There are many ways to generate this unique seed. In the below code, I demonstrate three of them : 1. Use a value that depends on the current time. However, since your loop runs so fast, the system time does not change significantly enough for seed values to change. Therefore, we must apply a trick... we must simulate a delay so that the time changes. I do this by setting the current thread to sleep for a very minimal time (so as not to affect program performance significantly). This is demonstrated by the function "SleepingWithRandom" in the code sample. 2. Use the loop counter as the seed value, since it is guaranteed to be unique for each iteration. This is demonstrated by the function "LoopingRandom" in the code sample. 3. Use a seed value derived from the loop value. If it is even, apply a bitwise complement of the current time (in ticks), else not. This would greatly increase the probability that the seed value generated is unique even for the same time. This is demonstrated by the function "ComplementingRandom" in the code sample. The code: (Syntax highlighted version available at: <http:// dotnetdevelopment.pastebin.com/m5236e4af>) --- using System; using System.Threading; interface IFoo { void foo(int a, int b); } class Factory : IFoo { private enum Operation { add = 1, subtract = 2, multiply = 3, divide = 4, } private int _a, _b; private int randomSeed = 0; public virtual void foo(int a, int b) { this._a = a; this._b = b; Random rand = new Random(randomSeed); Operation op = (Operation)rand.Next(1, 5); switch (op) { case Operation.add: plus(); break; case Operation.subtract: minus(); break; case Operation.multiply: multiplier(); break; case Operation.divide: dividor(); break; } //if (rand.Next(4) % 4 == 0) // plus(); //else if (rand.Next() % 4 == 1) // minus(); //else if (rand.Next() % 4 == 2) // dividor(); //else multiplier(); } public void plus() { Console.WriteLine("{0}+{1}={2}", _a, _b, _a + _b); } public void minus() { Console.WriteLine("{0}-{1}={2}", _a, _b, _a - _b); } public void dividor() { Console.WriteLine("{0}/{1}={2}", _a, _b, _a / _b); } public void multiplier() { Console.WriteLine("{0}*{1}={2}", _a, _b, _a * _b); } public int RandomSeed { set { randomSeed = value; } } } class MainClass { static void Main(string[] args) { IFoo[] df = new IFoo[10]; for (int i = 0; i < 10; i++) { Factory f = new Factory(); // Uncomment only one of the below 3 approaches at a time: //SleepingWithRandom(ref f, i); LoopingRandom(ref f, i); //ComplementingRandom(ref f, i); df[i] = f; } } private static void SleepingWithRandom(ref Factory f, int i) { // Generate a seed from the current time and set the seed value of the Random to be created. f.RandomSeed = unchecked((int)(DateTime.Now.Ticks)); f.foo(i + 1, i + 1); // Initiate a delay so as to increase randomness. Thread.Sleep(20); } private static void LoopingRandom(ref Factory f, int i) { // Generate a different seed using the loop variable itself. f.RandomSeed = i; f.foo(i + 1, i + 1); } private static void ComplementingRandom(ref Factory f, int i) { // Generate a different seed based on whether the loop variable is even or odd. if (i % 2 == 0) f.RandomSeed = ~unchecked((int)(DateTime.Now.Ticks)); else f.RandomSeed = unchecked((int)(DateTime.Now.Ticks)); f.foo(i + 1, i + 1); } } --- I think the "LoopingRandom" method should be sufficient for your purposes. You can therefore remove the extraneous code which is only for illustration of all three approaches to the problem. Note that I commented your if-else constructs and used an Enum variable instead. I think it's more "intuitive", this way !
<<inline: winmail.dat>>
