简体   繁体   中英

How to combine derived and base class objects into derived class object

Suppose I have this kind of model structure.

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.

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. SO how do I combine them into derived class object? I do not want to do this manually by assigning the base object's properties to the derived 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. You avoid creating temporary objects and avoid to copy properties from an object to another.

Hint: You can even avoid a method call, by invoking getAbcObject from within getXyzObject.

EDIT: As per CaiusJard suggestion, that I totally agree with, and based on my previous hint.. better method declaration should be

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

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"

I then would implement something like a CopyTo method inside the classes.

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.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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