views:

108

answers:

5

I have 3 Subclasses " Staff, Faculty, Student" each class is getting the users first initial lastname from the parent class person, to this id like to add 4 random numbers when the console application is run. The problem I am having is that all of the classes are getting the same 4 digits how can I fix this and yes it has to be done using Random I cant use static counters.

Person.cs "Parent Class"

public class Person
    {
        static string title;
        protected string firstName;
        protected string lastName;
        protected string address;
        protected string gender;
        protected string dateOfBirth;
        protected string userID;
        protected Random rnd = new Random();

Faculty.cs

namespace Person
{
    public class Faculty : Person
    {
        public Faculty(string aTitle, string aFirstName, string aLastName, string aAddress,
           string aGender, string aDateOfBirth)
            : base(aTitle, aFirstName, aLastName, aAddress,
                    aGender, aDateOfBirth)
        {


            this.userID = firstName.Substring(0, 1) + lastName.Substring(0, 5);

            this.userID = this.userID + rnd.Next(1000, 9999);

            Console.WriteLine(this.userID);
        }


    }
}

Staff.cs

namespace Person
{
    public class Staff : Person
    {
        public Staff(string aTitle, string aFirstName, string aLastName, string aAddress,
           string aGender, string aDateOfBirth)
            : base(aTitle, aFirstName, aLastName, aAddress,
                    aGender, aDateOfBirth)
        {

            this.userID = firstName.Substring(0, 1) + lastName.Substring(0, 5);

            this.userID = this.userID + rnd.Next(1000, 9999);

            Console.WriteLine(userID);
        }


    }
}

Test Class

   public class PersonTest
    {
       static void Main(string[] args) 
      {
          Person testPerson = new Faculty(" Mr.", "Merry ", "Lanes", " 493 Bluebane RD", "Male", " 8-06-1953\n ");


          Person studentPerson = new Student(" Mr.", "Jerry ", "Panes", " 456 Greenbane RD", "Male", " 8-10-1945\n");


          Person staffPerson = new Staff(" Mr.", "Joe ", "Gaines", " 495 Redbane RD", "Male", " 8-21-1989\n ");


            Console.ReadLine();
        }//end main
+5  A: 

I'm not seeing where you are declaring and initializing rnd. I'm gonna guess that it's declared as an instance member in Person, and initialized in Person's constructor -- always default initiialized, which means that it uses the time as the seed, which means that all call with a millisecond get the same seed.

Make rnd a static member, and initialize it once in a static ctonstructor.

UPDATE: This should be all that's needed:

static readonly protected Random rnd = new Random();

(It will also be faster, since you are creating a new Random object only once, instead of once for each object. Creating a seed from the clock is rather slow.)

James Curran
this fixed it protected static Random rnd = new Random();
Michael Quiles
thank you for your explanations everyone, it is very much appreciated
Michael Quiles
A: 

Random numbers require a seed in order to start - it's just a formula at the end of the day. If they start at the same place, they arrive at the same place.

Here is a tutorial:

http://articles.techrepublic.com.com/5100-10878_11-5663283.html

Adam
+3  A: 

If you can, would recommend rethinking this design

  1. Any form of hashing cannot guarantee uniqueness
  2. If you do need uniquely random userIds, then you will need to use something larger, like a GUID, or retain a persistent list of all UserIds which have already been issued.

But as you are suggesting in your post, an ideal way IMHO would be to use singleton or storage (e.g. SQL identity) which tracked the last issued UserId.

nonnb
Agreed: 1000-9999, at pseudo-random, doesn't inspire confidence about uniqueness.
Steven Sudit
I would but this code is from class and were supposed to finish it for HW.
Michael Quiles
A: 

The problem is, I think, that you initialize your Random objects in close succession and because the system clock has a finite resolution the objects get the same seed. The solution is to use the same Random object for all three classes.

More information:

http://msdn.microsoft.com/en-us/library/system.random.aspx

André Laszlo
...but nonnb is still right.
André Laszlo
+1  A: 

Make rnd static and initialize immediately, this should be the quickest ever solution to your problem.

As I understand rnd is protected/public field/property in your base class, so having it static will create random generator on first accessing of your Person type.

public class Person
{
    protected static Random rnd = new Random();
}

public class PersonImpl : Person
{
    public void DoSomething()
    {
        int a = rnd.Next(100, 9999);
    }
}
Andriy Buday
I wonder if the OP can use a static Random() if he can't use a static counter.
Henk Holterman
Yes, static counter should be better solution, but he said he need it to be random :)
Andriy Buday
Static random works, I cant use static counter cause were using this in class at the moment and to be on the same page as the others I cant deviate that much.
Michael Quiles