派生和基类,我可以明确设置基数吗?

时间:2011-01-28 01:04:25

标签: c# reflection copy-constructor derived-class

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 个答案:

答案 0 :(得分:11)

我在子类中使用这样的东西,它对我来说很好用:

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

答案 1 :(得分:3)

如果我正确地理解你的问题(并且我不完全确定我是),那么你可以通过做这样的事情来获得你想要的行为:

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 :(得分:2)

这是不可能的。

您需要手动设置属性。

答案 3 :(得分:1)

您只能复制其他类的内容,但不能直接设置。请参阅下面的示例,使用所谓的复制构造函数。

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()

答案 4 :(得分:1)

总体上有很多有用的评论。我认为简短的答案是由pst给出的,我认为这是正确的:

号。原因很简单:没有单独的基础对象。 (对象)这个==(对象)base总是如此。但是有一些方法可以通过反射(和其他方法)进行克隆/复制。也许描述真正想要的东西

所以,他对使用automapper工具的建议也非常有用,基本上就是我想要的。

答案 5 :(得分:0)

首先,每个SuperCar对象与另一个不同。 继承可帮助您定义相关对象的常见行为,但这并不意味着它们是相同的对象。类型的每个对象都有自己的构造过程。在创建子对象之前,将根据继承层次结构创建基类的对象。如果您希望为所有SuperCar对象使用公共属性,则需要在SuperCar实例中维护Car对象的单独实例,将公共汽车对象分配到SuperCar中的car对象并覆盖从Base Car派生的属性对象并将其重定向到道具。内部Car对象。

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

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

但我相信,这种设计与你想要的方式有关。如果您能让我们了解您为什么要这样做的大图,我们可能会提出更好的设计来满足您的要求。

答案 6 :(得分:0)

如果您希望获得比复制反射属性更多的控制权,请尝试应用Builder模式。 T可以是从BaseClass派生的任何类。

 public static T BuildNew<T>(BaseClass baseClass) where T : BaseClass, new()
 {
    return new T
    {
        Property1 = baseModel.Property1,
        Property2 = baseModel.Property2,
    };
 }