Function to clone an arbitrary object

2019-05-07 01:20发布

问题:

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?

回答1:

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!



回答2:

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