Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Function to clone an arbitrary object

I'm looking at a way to clone an object that is not known at compile time (or run-time, I think). The exact wording of the question is "Write a function that can clone an arbitrary object" E.g.

  • Pass unknown object to function.
  • Return a Deep Copy of object.

I'm guessing I will need to use Reflection to read the functions and variables, and then some how create a new object and assign these values to it. I could just use the Type.GetType() to find the type and create a new instance, then use this known object's copy constructor. But I'm not sure whether a given class will have one implemented (Deep), or whether the question is asking for such a solution (doesn't help that I don't understand what the required outcome is!).

Could someone guide me in the right direction, with Classes/Interfaces required, and Pseudo code if you're feeling generous, to achieve this?

like image 260
nf313743 Avatar asked Sep 04 '12 12:09

nf313743


2 Answers

You can simply Serialize and Deserialize an object to make a clone.
The following function will do that:

public object Clone(object obj)
{
    MemoryStream ms = new MemoryStream();
    BinaryFormatter bf = new BinaryFormatter();
    bf.Serialize(ms, obj);
    ms.Position = 0;
    object obj_clone = bf.Deserialize(ms);
    ms.Close();
    return obj_clone;
}
like image 90
MBZ Avatar answered Oct 14 '22 21:10

MBZ


This can be achieved by utilizing the

Type newObjectType = orgObject.GetType()

and then calling the Activator.CreateInstance(newObjectType). What you then has to do is loop through all properties of the object and set them on the new object. This can as well be done via reflection.

Loop through each PropertyInfo in orgObject.GetType().GetProperties() and set the value on the new object.

This should indeed create a "deep" copy of the object, independent of what type it is.

EDIT: Untested code example of the method I explained above.

Type newObjectType = orgObject.GetType();
object newObject = Activator.CreateInstance(newObjectType);

foreach (var propInfo in orgObject.GetType().GetProperties())
{
    object orgValue = propInfo.GetValue(orgObject, null);

    // set the value of the new object
    propInfo.SetValue(newObject, orgValue, null);
}

Hope you got some clarity!

like image 28
westin Avatar answered Oct 14 '22 20:10

westin