主类用户和子类播放器,如何播放器=用户?c#.

本文关键字:用户 播放器 子类 | 更新日期: 2023-09-27 18:35:21

我正在制作第一个服务器客户端应用程序,我需要你的帮助。
客户端必须自点,然后才能玩一些游戏。
所以我有 USER 和 PLAYER 类:USER 编译所有注册的用户,PLAYER 编译玩游戏的用户(有 PLAYER_GAME1、PLAYER_GAME2 等)。
在用户内部,我有姓名,姓氏,ID等专有信息。
在播放器中,我需要有用户的专有加上点,游戏时间等。

实际上:

     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*
     }
    }

所以为了获得名字,我必须做:

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

我认为更聪明的是使USER的PLAYER子类,当用户想要玩游戏时,我用播放器的专有"扩展"类用户,所以我需要做:

            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*
             }
            }

所以为了获得名字,我会这样做:

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

我知道 SUBCLASS=MAINCLASS 是不可能的,所以我该怎么做呢?

主类用户和子类播放器,如何播放器=用户?c#.

据我了解,您希望根据User信息创建一个Player角色。

如果我们的类是:

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)
    {
    }
}

此类构造函数的用法将是:

var player = new Player(user);

可以使用接受User信息的构造函数。您还可以编写扩展方法.ToPlayer()或类似的东西。

我认为您应该阅读有关 MSDN 上继承的文章,并继续阅读构造函数文章。


更新:

我已经理解你的问题,但不幸的是,没有简单的解决方案。您可以保留当前解决方案,如果您的应用程序基于一个用户创建许多播放器,这将没问题。如果是一对一关系,您可以执行以下操作:

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)
    {
    }
}

此解决方案的主要问题是您必须自己复制它,没有任何自动化机制。你可以在这里找到一个类似的问题:

从派生类复制基类的内容

根据您的澄清要求,并且仅通过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*
   }
}

所以现在,在从用户扩展的播放器中使用相同的参数构造函数参数,您实际上可以直接使用 parms 创建播放器,也可以间接绕过用户通过。

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

或作为使用用户实例的结果

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

这是否有助于为您阐明多个类实现的一些初始化?