简体   繁体   English

如何将派生和基础 class 对象组合成派生 class object

[英]How to combine derived and base class objects into derived class object

Suppose I have this kind of model structure.假设我有这种 model 结构。

class Abc{
public string A{get;set;}
public string B{get;set;}
}
class Xyz:Abc{
public string C{get;set;}
public string D{get;set;}
}

Now in one method in a separate class, I am fetching objects of both classes individually from the source.现在,在单独的 class 中的一种方法中,我从源中分别获取两个类的对象。

public Xyz Test(){
var abc = getAbcObject();
var xyz = getXyzObject();// this only initialize properties which are in Xyz class
}

Here my method is returning object of derived class.这里我的方法是返回派生的 class 的 object。 SO how do I combine them into derived class object?那么如何将它们组合成派生的 class object? I do not want to do this manually by assigning the base object's properties to the derived object.我不想通过将基础对象的属性分配给派生的 object 来手动执行此操作。

EDIT: I do not have control over the source from where I am getting the values and I cannot make any changes over there.编辑:我无法控制获取值的来源,也无法在那里进行任何更改。

I would rewrite Test and get methods as follow:我将重写测试并获取方法如下:

public Xyz Test()
{
    var xyz = new Xyz();
    getAbcObject(xyz);
    getXyzObject(xyz);
}
public void getAbcObject(Abc abc)
{
    abc.A = "A";
    abc.B = "B";
}
public void getXyzObject(Xyz xyz)
{
    xyz.C = "C";
    xyz.D = "D";
}

This way, every get method is responsible only for the fields it know and you are free to create the object of the proper class once, without creating temporary objects of base classes that probably later will be discarded.这样,每个 get 方法只对它知道的字段负责,您可以自由地创建适当的 class 的 object 一次,而无需创建可能稍后将被丢弃的基类的临时对象。 You avoid creating temporary objects and avoid to copy properties from an object to another.您避免创建临时对象并避免将属性从 object 复制到另一个。

Hint: You can even avoid a method call, by invoking getAbcObject from within getXyzObject.提示:您甚至可以通过从 getXyzObject 中调用 getAbcObject 来避免方法调用。

EDIT: As per CaiusJard suggestion, that I totally agree with, and based on my previous hint.. better method declaration should be编辑:根据 CaiusJard 的建议,我完全同意,并且基于我之前的提示.. 更好的方法声明应该是

public Xyz Test()
{
    var xyz = new Xyz();
    //FillAbcObject(xyz); // invoked by FillXyzObject
    FillXyzObject(xyz);
}
public void FillAbcObject(Abc abc)
{
    abc.A = "A";
    abc.B = "B";
}
public void FillXyzObject(Xyz xyz)
{
    FillAbcObject(xyz);

    xyz.C = "C";
    xyz.D = "D";
}

Based on recent OP edit基于最近的 OP 编辑

I do not have control over the source from where I am getting the values and I cannot make any changes over there.我无法控制获取值的来源,也无法在那里进行任何更改。

that I understand as "getAbcObject and getXYZObject are not modifiable and I have to call them"我理解为“getAbcObject 和 getXYZObject 不可修改,我必须调用它们”

I then would implement something like a CopyTo method inside the classes.然后我会在类中实现类似于 CopyTo 方法的东西。

class Abc
{
    public string A { get; set; }
    public string B { get; set; }

    public virtual void CopyTo(Abc other)
    {
        other.A = this.A;
        other.B = this.B;
    }
}
class Xyz : Abc
{
    public string C { get; set; }
    public string D { get; set; }

    public override sealed void CopyTo(Abc other)
    {
        if (other is Xyz)
            this.CopyTo(other as Xyz);
        else
            base.CopyTo(other);
    }
    public virtual void CopyTo(Xyz other)
    {
        base.CopyTo(other);

        other.C = this.C;
        other.D = this.D;
    }
}

And change Test method as follow:并更改测试方法如下:

public Xyz Test()
{
    var abc = getAbcObject();
    var xyz = getXyzObject();
    abc.CopyTo(xyz);
}

As situation can't be changed: copying properties is not a big deal.由于情况无法改变:复制属性没什么大不了的。

foreach (var prop in abc.GetType().GetProperties(System.Reflection.BindingFlags.Public | System.Reflection.BindingFlags.Instance))
{
    xyz.GetType().GetProperty(prop.Name).SetValue(xyz, prop.GetValue(abc));
}

[Edit] Maybe check for CanRead and CanWrite of the properties. [编辑] 也许检查 CanRead 和 CanWrite 的属性。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM