Производный и базовый класс, могу ли я установить базу явно? - PullRequest
16 голосов
/ 28 января 2011
public class SuperCar: Car
{
     public bool SuperWheels { get {return true; } }
}

public class Car 
{
     public bool HasSteeringWheel { get {return true;} }
}

Как я могу установить базовый класс для производного Суперкара?

Например, я хочу просто установить базовый класс SuperCars следующим образом:

public void SetCar( Car car )
{
SuperCar scar = new SuperCar();
car.Base = car; 
}

В основном, еслиУ меня есть объекты Car, я не хочу вручную проходить через все свойства автомобиля, чтобы настроить объект SuperCar, и я думаю, что это единственный способ, которым вы можете это сделать, но если вы можете сделать это иначе, это будет оооченьнамного лучше.

Ответы [ 7 ]

11 голосов
/ 25 сентября 2013

Я использую что-то вроде этого в подклассе, и оно прекрасно работает для меня:

using System.Reflection;
.
.
.
/// <summary> copy base class instance's property values to this object. </summary>
private void InitInhertedProperties (object baseClassInstance)
{
    foreach (PropertyInfo propertyInfo in baseClassInstance.GetType().GetProperties())
    {
        object value = propertyInfo.GetValue(baseClassInstance, null);
        if (null != value) propertyInfo.SetValue(this, value, null);
    }
}
3 голосов
/ 28 января 2011

Если я правильно понимаю ваш вопрос (и я не совсем уверен в этом), то вы можете получить желаемое поведение, выполнив что-то вроде этого:

class Car {
    public bool CarProperty { get; set; }
    // regular constructor
    public Car() {

    }
    // "copy" constructor
    public Car(Car c) {
        CarProperty = c.CarProperty;
    }
}

class SuperCar : Car {
    public bool SuperCarProperty { get; set; }
    // regular constructor
    public SuperCar() {
    }
    // "copy" constructor
    public SuperCar(Car c) : base(c) {
        SuperCar sc = c as SuperCar;
        if(sc != null) {
            SuperCarProperty = sc.SuperCarProperty;
        }
    }

ТогдаВы можете сделать это:

public void SetCar(Car car) {
    SuperCar scar = new SuperCar(car);
}

Обратите внимание, что вы должны быть очень осторожны в своем конструкторе "копирования", чтобы не копировать свойства таким образом, чтобы два объекта совместно использовали одни и те же члены (ссылки), когда они не должны.

Я должен спросить, однако, какова ваша цель с этим?

2 голосов
/ 28 января 2011

Это невозможно.

Вам необходимо вручную установить свойства.

1 голос
/ 18 октября 2011

В целом много полезных комментариев. Я думаю, что короткий ответ дал pst, и я думаю, что это правильно:

Нет. Короткая причина: нет отдельного базового объекта. (объект) это == (объект) основание всегда верно. Есть способы выполнить клонирование / копирование с помощью отражения (и других средств). Возможно, опишите, что действительно нужно

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

1 голос
/ 28 января 2011

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

class Car
{
    string model;
    public Car(string model) { this.model = model; }
    protected Car(Car other) { this.model = other.model; }
    string Model { get; set; }
}

class SuperCar : Car
{
    public SuperCar(Car car) : base(car) { }
    public SuperCar(string model) : base(model) { }
    bool IsTurbo { get; set; }
}

Ключом является ключевое слово base() после объявления конструктора.

0 голосов
/ 04 ноября 2017

Если вы хотите иметь больше контроля, чем копировать отраженные свойства, попробуйте применить шаблон Builder. T может быть любым классом, производным от BaseClass.

 public static T BuildNew<T>(BaseClass baseClass) where T : BaseClass, new()
 {
    return new T
    {
        Property1 = baseModel.Property1,
        Property2 = baseModel.Property2,
    };
 }
0 голосов
/ 28 января 2011

Прежде всего, каждый объект SuperCar отличается от другого. Наследование помогает определить общее поведение связанных объектов. Это не означает, что они являются одними и теми же объектами. Каждый объект типа имеет свой собственный процесс конструирования.Перед созданием дочернего объекта объект базового класса создается в соответствии с иерархией наследования.Если вы хотите использовать общее свойство для всех объектов SuperCar, вам необходимо сохранить отдельный экземпляр объекта Car в экземпляре SuperCar, назначить общий объект car в объект car в SuperCar и переопределить свойства, полученные из базового Carобъект и перенаправить его на реквизит.внутреннего автомобильного объекта.

public class SuperCar: Car
{
     public bool SuperWheels { get {return true; } }

     Car carInstance = null;
     public void SetCar( Car car )
     {
         carInstance = car; 
     }
}

Но я уверен, что с этим дизайном что-то не так, как вы хотите.Если вы можете сообщить нам более широкую картину того, почему вы хотите это сделать, мы можем придумать лучший дизайн для удовлетворения ваших требований.

...