приведите родительский объект к дочернему объекту в C # - PullRequest
19 голосов
/ 27 марта 2012

Привет, я хочу привести родительский объект к дочернему объекту в C #

public class Parent
{
    public string FirstName {get; set;}
    public string LastName {get; set;}
    public string City {get; set;}
}

public class Child : Parent
{
    public string PhoneNumber {get; set;}
    public string MobileNumber {get; set;}
}

. Теперь сценарий представляет собой список родительского объекта, и я хочу создать список дочерних объектов, чтобы я мог расширитьинформация

List<Parent> lstParent;
List<Child> lstChild = new List<Child>();

foreach(var obj in lstParent)
{
    lstChild.add((Child)obj);
}

как унаследованный родительский класс дочернего класса, поэтому у дочернего класса уже есть член родительского класса, я просто хочу заполнить их автоматически, чтобы я мог заполнить элемент данных дочернего класса

Ответы [ 7 ]

23 голосов
/ 21 сентября 2012

Я делаю так ( это просто пример ):

using System.Reflection;

public class DefaultObject
{
    ...
}

public class ExtendedObject : DefaultObject
{
    ....
    public DefaultObject Parent { get; set; }

    public ExtendedObject() {}
    public ExtendedObject(DefaultObject parent)
    {
        Parent = parent;

        foreach (PropertyInfo prop in parent.GetType().GetProperties())
            GetType().GetProperty(prop.Name).SetValue(this, prop.GetValue(parent, null), null);
    }
}

Использование:

DefaultObject default = new DefaultObject { /* propery initialization */ };
ExtendedObject extended = new ExtendedObject(default); // now all properties of extended are initialized by values of default properties.
MessageBox.Show(extended.Parent.ToString()); // now you can get reference to parent object
19 голосов
/ 27 марта 2012

Если я правильно понимаю ваш комментарий «Я просто хочу заполнить их автоматически», вы захотите создать новый дочерний объект, который будет заполнен значениями родительского элемента со значениями по умолчанию для новых свойств.Лучший способ сделать это - создать конструктор, который копирует значения:

public class Parent
{
   public string FirstName {get; set;}
    public string LastName {get; set;}
    public string City {get; set;}
}

public class Child : Parent
{
    public string PhoneNumber {get; set;}
    public string MobileNumber {get; set;}

    public Child (Parent parentToCopy)
    {
        this.FirstName = parentToCopy.FirstName;
        this.LastName = parentToCopy.LastName;
        this.City = parentToCopy.City;

        this.PhoneNumber = string.Empty; // Or any other default.
        this.MobileNumber = string.Empty;
    } 
}

Теперь вы можете использовать LINQ, как и ответы выше, для создания дочернего элемента каждого родителя:

List<Child> lstChild = lstParent.Select(parent => new Child(parent)).ToList();

Обратите внимание, что это очень похоже на ответ @ daryal, но оборачивает логику копирования между родителями внутри конструктора, а не выводит ее снаружи в вызове new Child().

6 голосов
/ 01 февраля 2014

Мне так понравилось:

class Parent
{
  ...
}

class Child :Parent
{
  ...
  public Child(Parent p)
  {
            foreach (FieldInfo prop in  p.GetType().GetFields())
                GetType().GetField(prop.Name).SetValue(this, prop.GetValue( p));

            foreach (PropertyInfo prop in  p.GetType().GetProperties())
                GetType().GetProperty(prop.Name).SetValue(this, prop.GetValue( p, null), null);
  }
}
4 голосов
/ 23 января 2015

Это то, что я придумал из моего решения.

    public static void ShallowConvert<T, U>(this T parent, U child)
    {
        foreach (PropertyInfo property in parent.GetType().GetProperties())
        {
            if (property.CanWrite)
            {
                property.SetValue(child, property.GetValue(parent, null), null);
            }
        }
    }
2 голосов
/ 27 марта 2012

Вы также можете использовать отражение, но это проще для вашего случая.

foreach(var obj in lstParent)
{
    Child child = new Child(){ FirstName = obj.FirstName, LastName=obj.LastName, City = obj.City};
    child.MobileNumber = "some mobile number";
    child.PhoneNumber = "some phone number";
    lstChild.Add((Child)obj);
}
2 голосов
/ 27 марта 2012
var lstChild = lstParent.Cast<Child>().ToList();

или

var lstChild = lstParent.ConvertAll(x=>(Child)x);

Однако оба они предполагают, что список Parent на самом деле содержит Child экземпляров. Вы не можете изменить фактический тип объекта.

0 голосов
/ 09 января 2018

Downcast - термин, используемый для описания приведения объекта родительского класса к дочернему классу.

Это не лучший метод, однако если вам нужно быстрое решение, вы можете попробовать привести родительский объектсначала к типу object, а затем приведите объект к дочернему типу.

Parent p = new Parent();

Child c = (Child)((object) p);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...