[ACCEPTED]-How to "clone" an object into a subclass object?-subclass

Accepted answer
Score: 11

I would add a copy constructor to A, and 3 then add a new constructor to B that takes 2 an instance of A and passes it to the base's 1 copy constructor.

Score: 10

There is no means of doing this automatically 5 built into the language...

One option is 4 to add a constructor to class B that takes 3 a class A as an argument.

Then you could 2 do:

B newB = new B(myA);

The constructor can just copy the relevant 1 data across as needed, in that case.

Score: 5

You can achieve this by using reflection.

Advantage: Maintainability. No 10 need for changing copy-constructor or similar, adding 9 or removing properties.

Disadvantage: Performance. Reflection 8 is slow. We're still talking milliseconds 7 on average sized classes though.

Here's a 6 reflection-based shallow copy implementation 5 supporting copy-to-subclass, using extension 4 methods:

public static TOut GetShallowCopyByReflection<TOut>(this Object objIn) 
    Type inputType = objIn.GetType();
    Type outputType = typeof(TOut);
    if (!outputType.Equals(inputType) && !outputType.IsSubclassOf(inputType)) throw new ArgumentException(String.Format("{0} is not a sublcass of {1}", outputType, inputType));
    PropertyInfo[] properties = inputType.GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
    FieldInfo[] fields = inputType.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.FlattenHierarchy);
    TOut objOut = (TOut)Activator.CreateInstance(typeof(TOut));
    foreach (PropertyInfo property in properties)
            property.SetValue(objOut, property.GetValue(objIn, null), null);
        catch (ArgumentException) { } // For Get-only-properties
    foreach (FieldInfo field in fields)
        field.SetValue(objOut, field.GetValue(objIn));
    return objOut;

This method will copy all properties 3 - private and public, as well as all fields. Properties 2 are copied by reference, making it a shallow 1 copy.

Unit tests:

public class ExtensionTests {
    public void GetShallowCloneByReflection_PropsAndFields()
        var uri = new Uri("http://www.stackoverflow.com");
        var source = new TestClassParent();
        source.SomePublicString = "Pu";
        source.SomePrivateString = "Pr";
        source.SomeInternalString = "I";
        source.SomeIntField = 6;
        source.SomeList = new List<Uri>() { uri };

        var dest = source.GetShallowCopyByReflection<TestClassChild>();
        Assert.AreEqual("Pu", dest.SomePublicString);
        Assert.AreEqual("Pr", dest.SomePrivateString);
        Assert.AreEqual("I", dest.SomeInternalString);
        Assert.AreEqual(6, dest.SomeIntField);
        Assert.AreSame(source.SomeList, dest.SomeList);
        Assert.AreSame(uri, dest.SomeList[0]);            

internal class TestClassParent
    public String SomePublicString { get; set; }
    internal String SomeInternalString { get; set; }
    internal String SomePrivateString { get; set; }
    public String SomeGetOnlyString { get { return "Get"; } }
    internal List<Uri> SomeList { get; set; }
    internal int SomeIntField;

internal class TestClassChild : TestClassParent {}
Score: 4

Using Factory Method Pattern:

    private abstract class A
        public int P1 { get; set; }

        public abstract A CreateInstance();

        public virtual A Clone()
            var instance = CreateInstance();
            instance.P1 = this.P1;
            return instance;

    private class B : A
        public int P2 { get; set; }

        public override A CreateInstance()
            return new B();

        public override A Clone()
            var result = (B) base.Clone();
            result.P2 = P2;
            return result;

    private static void Main(string[] args)
        var b = new B() { P1 = 111, P2 = 222 };

        var c = b.Clone();


Score: 1

Create a ctor in B that allows one to pass 2 in an object of type A, then copy the A 1 fields and set the B fields as appropriate.

Score: 0

You could make a Convert method on class 3 B that takes in the base class.

public ClassB Convert(ClassA a)
   ClassB b = new ClassB();
   // Set the properties
   return b;

You could 2 also have a constructor for ClassB take 1 in an object of ClassA.

Score: 0

No, you can't do that. One way to achieve 4 this is to add a constructor on class B 3 that accepts a parameter of type B, and 2 add data manually.

So you could have something 1 like this:

public class B
  public B(A a)
    this.Foo = a.foo;
    this.Bar = a.bar;
    // add some B-specific data here
Score: 0

In your base class add the CreateObject 4 virtual method below...

    public virtual T CreateObject<T>()
        if (typeof(T).IsSubclassOf(this.GetType()))
            throw new InvalidCastException(this.GetType().ToString() + " does not inherit from " + typeof(T).ToString());

        T ret = System.Activator.CreateInstance<T>();

        PropertyInfo[] propTo = ret.GetType().GetProperties();
        PropertyInfo[] propFrom = this.GetType().GetProperties();

        // for each property check whether this data item has an equivalent property
        // and copy over the property values as neccesary.
        foreach (PropertyInfo propT in propTo)
            foreach (PropertyInfo propF in propFrom)
                if (propT.Name == propF.Name)

        return ret;

then say you want 3 to create a real life subclass object from 2 the super class just call


That should do 1 it!

Score: 0

While no one suggested this (and this won't 13 work for everyone, admittedly), it should 12 be said that if you have the option of creating 11 object b from the get-go, do that instead 10 of creating object a then copying to object 9 b. For example, imagine that you are in 8 the same function and have this code:

var a = new A();
a.prop1 = "value";
a.prop2 = "value";
// now you need a B object instance...
var b = new B();
// now you need to copy a into b...

Instead 7 of worrying about that last commented step, just 6 start with b and set the values:

var b = new B();
b.prop1 = "value";
b.prop2 = "value";

Please don't 5 downvote me because you think the above 4 is stupid! I have encountered many programmers 3 who are so focused on their code that they 2 didn't realize a simpler solution is staring 1 them in the face. :)

More Related questions