1

I'm making the first server-client application and i need your help.
The client must autenticate itself and after it can play some games.
So I've got USER and PLAYER classes: USER comprends all user registered and PLAYER comprends user that play game (there are PLAYER_GAME1,PLAYER_GAME2, etc..).
Inside USER i've proprieties like name, surname, id and etc.
Inside PLAYER i need have the proprieties of the user plus point, time in game, etc.

Actually:

     public class USER
{
        public string name, surname, ID, password, IP;
        WALLET wallet;
        bool login;
        datetime lastAccess;
        TcpClient socket;    
        Thread receiveMessages;//this receive message for log-in
        ...*other 30 proprieties*
     public USER(string n,string s,string _id,string pw)
    {
     *inizialize all variables*
    }
   }

   public class PLAYER
    {
      public USER user;
        Thread receiveMessages;
        int points;
        bool online;
        ...*other proprieties*

     public PLAYER(USER u)
     {
      user=u;
     *inizialize all variables*
     }
    }

so for getting name i have to do:

PLAYER p= new PLAYER(new USER(...));
string name=p.user.name;

I think is more smart make PLAYER subclass of USER and when user want play games i "expand" the class user with the proprieties of player so i need do :

            public class USER
            {
                protected string name, surname, ID, password, IP;
                WALLET wallet;
                bool login;
                datetime lastAccess;
                TcpClient socket;    
                Thread receiveMessages;//this receive message for meneage the game
                ...*other 30 proprieties*

             public USER(string n,string s,string _id,string pw)
            {
             *inizialize all variables*
            }
           }

           public class PLAYER : USER
            {
                Thread receiveMessages;
                ...*other proprieties*

             public PLAYER():base()// here, what could i do?
             {
             *inizialize all PLAYER variables*
             }
            }

so for getting name i would do:

PLAYER p= new PLAYER();
p=exixtingUser;
string name=p.name;

I know that SUBCLASS=MAINCLASS is impossible so how could i do it?

Leonardo Rignanese
  • 865
  • 11
  • 22

2 Answers2

1

As I can understand, you want to create a Player role based on the User information.

If our classes are:

public class User
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }

    public User(Guid id, string name)
    {
        Id = id;
        Name = name;
    }
}

public class Player : User
{
    public TimeSpan TimeInGame { get; set; }

    public Player(User userInfo)
        : base(userInfo.Id, userInfo.Name)
    {

    }
}

usage of such constructor will be:

var player = new Player(user);

You can use a constructor accepting the User information. You also can write the extension method .ToPlayer() or something like it.

I think you should read the article about inheritance on the MSDN and continue the reading with Constructors articles.


Update:

I've understood your problem, but, unfortunately, there is no easy solution for it. You can either remain on your current solution, this will be alright if your application creates many players based on one user. If it is a -one-to-one relation, you can do something like this:

public class User
{
    public Guid Id { get; private set; }
    public string Name { get; private set; }

    public User(User copyFrom)
    {
        Id = copyFrom.Id;
        Name = copyFrom.Name;
        // copy all the fields you need
    }
}

public class Player : User
{
    public TimeSpan TimeInGame { get; set; }

    public Player(User userInfo)
        : base(userInfo)
    {

    }
}

The main problem of this solution is that you have to copy it by yourself, without any automation mechanism. You can find a similar question here:

Copying the contents of a base class from a derived class

Community
  • 1
  • 1
VMAtm
  • 27,943
  • 17
  • 79
  • 125
  • this code is right but look the code that i've add. My problem is pass all the proprieties into PLAYER (there are a lot! I can't make a contructor with 30 parameters) – Leonardo Rignanese Dec 28 '14 at 12:48
  • @LeonardoRignanese, VMAtm is on target with your needs and how I would have offered it too. Create an instance of the player based on known user. From there, if you have other things you need to pass on, I would create that as a secondary method exposed on the player object preparing those other settings, which could be other class instances or structures that in themselves could have plenty of fields to pull values from. – DRapp Dec 28 '14 at 13:03
  • @DRapp thanks. there is a method for doing :base(USER u) and inside do base=u; ? Can you give me an example? – Leonardo Rignanese Dec 28 '14 at 13:45
  • @LeonardoRignanese So it's not a one-to-one, and is many-to-one, many players to one user. – VMAtm Dec 30 '14 at 09:48
  • @VMAtm the relation is one-to-one and is dinamic: one user can be player_game1 and after can be player_game2. I've decided to leave the class without polimorphism because there are a lot of proprieties in USER and i prefer get it by a method inside PLAYER that return the specific USER propriety. Thank you very much the same! OT: What is the advantage of Guid instead String ? I checked manually before the registration if the ID already exist with an hashtable. – Leonardo Rignanese Dec 30 '14 at 09:48
  • @LeonardoRignanese Hashes of some strings can be equal. Guid are (practically) unique. And indexes based on guid are faster. But don't create them as clustered indexes. – VMAtm Dec 30 '14 at 09:52
0

Per your request of clarification, and to only offer expansion of the nice solution by VMAtm.

public class USER
{
   // changed to public getters so externally can be accessed
   // for read-only, but write access for USER instance or derived class (PLAYER)
   // QUESTIONABLE on public accessor on password
   public string name { get; protected set; }
   public string surname { get; protected set; }
   public string ID { get; protected set; }
   public string password { get; protected set; }
   public string IP { get; protected set; }

   WALLET wallet;
   bool login;
   datetime lastAccess;
   TcpClient socket;    
   // make this too protected AND available to player AND any others that make sense above
   protected Thread receiveMessages; //this receive message for meneage the game
   ...*other 30 proprieties*

   public USER(string nm, string sur, string _id, string pw)
   {
      name = nm;
      surname = sur;
      ID = _id;
      password = pw;

      InitUserVars();
   }

   private InitUserVars()
   {
      *inizialize all variables*
   }

}

public class PLAYER : USER
{
   // removed the Thread receiveMessages;
   // as it is avail on parent class  USER
   ...*other proprieties*

   // slightly different option, instead, call the "THIS" version of constructor
   public PLAYER(USER ui) : this(ui.name, ui.surname, ui.ID, ui.password )
   {  }

   // Now, pass same initializing parms to the USER base class so that all still runs the same.  
   public PLAYER(string nm, string sur, string _id, string pw) : base(nm, sur, _id, pw)
   {
      // by calling the "base" above, all default behaviors are handled first

      // Now, we can do whatever else specific to the PLAYER
      InitPlayerVars()
   }


   private InitPlayerVars()
   {
      *inizialize variables associated with PLAYER that is NOT part of USER baseclass*
   }
}

So now, with the same parameter constructor arguments in the player expanded from the user, you can actually jump to creating a player directly with parms or indirectly by-passing a user via.

PLAYER p1 = new PLAYER( "name", "mr", 123, "mypassword" );

or as result using an INSTANCE of a USER

USER u1 = new USER( "name", "mr", 123, "mypassword" );
PLAYER p1 = new PLAYER(u1);

Does this help clarify some initialization of multiple class implementations for you?

DRapp
  • 47,638
  • 12
  • 72
  • 142
  • mmh ok, would be more comfortable and less cumbersome to incorporate the class USER inside the class PLAYER but thanks for all. – Leonardo Rignanese Dec 28 '14 at 15:02
  • @LeonardoRignanese, yes, that probably makes more sense, but lacking a more complete insight to your needs, expanded options of subclassed implementation. – DRapp Dec 28 '14 at 15:07