Как создать класс, который «частично наследует» другой класс или просто реализует некоторые члены и функции из другого класса? - PullRequest
0 голосов
/ 02 июля 2019

Как сказал заголовок, у меня есть класс, просто назовите его User, который должен реализовать некоторые свойства другого фиксированного класса UserData, но не все из них. Однако, это не работает, если я непосредственно заставляю User наследовать UserData, потому что в UserData есть некоторые виртуальные функции, которые не нужны в User. Так как мне поступить?

Кроме того, я бы не стал UserData наследовать User из-за некоторых ограничений бизнес-логики, и UserData не следует изменять или реализовывать какой-либо интерфейс.

UserData

public class UserData
{
    private string _aS;
    public string AS
    {
        get { return _aS; }
        set { _aS = value; }
    }

    private string _bS;
    public virtual string BS
    {
        get { return _bS; }
        set { _bS = value; }
    }

    private string _cS;
    public virtual string CS
    {
        get { return _cS; }
        set { _cS = value; }
    }
}

Пользователь

public class User
{
    private string _aS;     // Same as Daddy's
    public string AS
    {
        get { return _aS; }
        set { _aS = value; }
    }

    private string _bS;    // Same as Daddy's
    public virtual string BS
    {
        get { return _bS; }
        set { _bS = value; }
    }

    /* _cS should not be included in Baby */
}

1 Ответ

2 голосов
/ 02 июля 2019

C # использует интерфейсы для установки общих свойств и методов.

Используйте интерфейсы, которые определяют общие элементы обоих классов.

public Interface UserInfo
{

    string AS {get; set;}

    string BS {get; set;}
}

Вы все еще можете использовать базовый класс, он должен быть первым в списке, т.е. после ":".

public class UserData: UserInfo
public class User: UserInfo

Поскольку ОБА классы уже реализуют Интерфейс, нет никаких изменений, кроме как их вывод из интерфейса.

Редактировать

Поскольку класс UserData не может быть изменен (по какой-либо причине, определен извне или публично доступен через и API) и не является sealed, из него можно извлечь класс и добавить интерфейс:

public class UserData1: UserData, UserInfo
{
// since the base class already implements the public properties as defined 
// in the interface, no implementation is required here

// however any defined constructors in the base class must be present here:
    // repeat per constructor
    public UserData1() : base() // add parameters: UserData1(int i):base(i)
    {
      // this can be left empty
    }
}

Полностью вымышленный вариант использования:

Предполагает:

BusinessLogic.UserData передается методу как:

List<BusinessLogic.UserData> userData. и одно значение BusinessLogic.UserData для полноты.

Массив уровня класса, уже созданный и заполненный, доступен как public User[] users.

Для этого также требуется `использование System.Linq;" для массового преобразования типов.

public void ProcessAll(List<BusinessLogic.UserData> userData,BusinessLogic.UserData single)
{
   List<UserInfo> AllData = new List<UserInfo>();

   AllData.AddRange(userData.ConvertAll(new Converter<BusinessLogic.UserData, UserInfo>(i => i as UserData1))); 
   AllData.AddRange(users);
   // cast the single and add it to the list
   AllData.Add((UserInfo)((UserData1)single));// note the extra cast
   foreach(var user in AllData)
   {      
 //note CS is not available from AllData since it is not defined in the interface
      // not the most elegant code, but proves the point
      Console.WriteLine("AS=" + user.AS + " BS=" + user.BS);
   }
   //Let us replace the first element in userData with itself from AllData does nothing, but shows how to do this.
   if(AllData[0] is BusinessLogic.UserData)
//since add order is maintained in a list this if is not needed.
      userData[0] = (BusinessLogic.UserData)AllData[0];

   // since BusinessLogic.UserData is a reference type(class not struct) we can modify CS, but only if it is cast back to BusinessLogic.UserData first
   if(AllData[0] is BusinessLogic.UserData)
         ((BusinessLogic.UserData)AllData[0]).CS="Hello World";
}


Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...