posted on Saturday, March 04, 2006 10:38 AM
by
johnwood
Shallow Cloning Made Easy: Calling MemberwiseClone on non-cloneable objects
In my last post I wrote about a way to clone an object without having to implement ICloneable. It would use serialization to clone the object, by serializing the object to a memory stream and then deserializing immediately to create a new, copied instance of the object.
A reader pointed out that this performs a deep clone, while that depends on the serialization implementation for that class for most cases it's true.
The .Net framework gives us a base method called MemberwiseClone that copies the values of all the non-static fields of an object. Because it isn't recursive and just copies references as-is, MemberwiseClone doesn't perform a deep clone, rather it just performs a primitive shallow clone.
However this method is protected and is only available on the base class, object. This means we cannot invoke it on objects ourselves. Instead we're expected to implement ICloneable on the object and use MemberwiseClone to perform the shallow clone in the implementation.
So here's a simple bit of code that bypasses that restriction. The code lets you run MemberwiseClone on any object you pass in, therefore performing a shallow clone of any object.
public static object ShallowClone(object obj)
{
return typeof(object).GetMethod("MemberwiseClone", System.Reflection.BindingFlags.NonPublic
| System.Reflection.BindingFlags.Instance).Invoke(obj, new object[0]);
}
Put this method in your utilities class - it's static so you can run it from anywhere.
Note, though, that by running this method you're not guaranteed that the object will be in a consistent state, or that all the fields were actually cloned correctly. But in simple cases it should work.
Hope you find it useful.