Introduction
Below you can find a short article on how to do a deep copy of objects using Reflection in C#. Please be aware that this is my first article here (even first article in the English language...)
Background
The class (called HCloner
) has a DeepCopy
function. It drills down the entire object fields structure (using System.Reflection
) and copies it into a new location that is returned after that.
Members that are copied are fields - no need to copy properties since behind every property, there is a field. A property itself cannot hold any value.
Using the code
Let's look at the "core" code:
using System;
using System.Reflection;
namespace HAKGERSoft {
public class HCloner {
public static T DeepCopy<T>(T obj) {
if(obj==null)
throw new ArgumentNullException("Object cannot be null");
return (T)Process(obj);
}
static object Process(object obj) {
if(obj==null)
return null;
Type type=obj.GetType();
if(type.IsValueType || type==typeof(string)) {
return obj;
}
else if(type.IsArray) {
Type elementType=Type.GetType(
type.FullName.Replace("[]",string.Empty));
var array=obj as Array;
Array copied=Array.CreateInstance(elementType,array.Length);
for(int i=0; i<array.Length; i++) {
copied.SetValue(Process(array.GetValue(i)),i);
}
return Convert.ChangeType(copied,obj.GetType());
}
else if(type.IsClass) {
object toret=Activator.CreateInstance(obj.GetType());
FieldInfo[] fields=type.GetFields(BindingFlags.Public|
BindingFlags.NonPublic|BindingFlags.Instance);
foreach(FieldInfo field in fields) {
object fieldValue=field.GetValue(obj);
if(fieldValue==null)
continue;
field.SetValue(toret,Process(fieldValue));
}
return toret;
}
else
throw new ArgumentException("Unknown type");
}
}
}
Using it is very simple - just call the DeepCopy
function.
History
This is a very alpha-pre version of my function. I'm looking forward for some feedback from you - any issues found will be analysed and fixed (at least, I'll try).