【术】c#中利用反射实现深拷贝

时间:2023-02-07 19:57:01

c#中深拷贝不常用,但是需要的时候如果没有,实在是麻烦的很。今天聊天,中梁大神说他实现了一个,赶紧学习学习。废话少说,直接上代码。

using System;
using System.Collections;
using System.Collections.Generic;
using System.Reflection;

public class CloneHelper
{
public static object Clone(object obj)
{
Type type = obj.GetType();
object clone_obj = System.Activator.CreateInstance(type);
Copy(clone_obj, obj, type);
return clone_obj;
}

public static void Copy<T>(T dst, T src)
{
Copy(dst, src, typeof(T));
}

static void Copy(object dst, object src, Type type)
{
if (type.IsGenericType)
{
if (type.GetInterface("IList") != null)
{
IList list_obj = src as IList;
IList list_clone_obj = dst as IList;
foreach (object ele in list_obj)
{
Type ele_type = ele.GetType();
if (ele_type.IsPrimitive || ele_type.IsValueType || ele_type == typeof(String))
{
list_clone_obj.Add(ele);
}
else
{
list_clone_obj.Add(Clone(ele));
}
}
return;
}
else if (type.GetInterface("IDictionary") != null)
{
IDictionary dict_obj = src as IDictionary;
IDictionary dict_clone_obj = dst as IDictionary;
foreach (object key in dict_obj.Keys)
{
object value = dict_obj[key];
Type key_type = key.GetType();
if (key_type.IsPrimitive || key_type.IsValueType || key_type == typeof(String))
{
if (key_type.IsPrimitive || key_type.IsValueType || key_type == typeof(String))
{
dict_clone_obj.Add(key, value);
}
else
{
dict_clone_obj.Add(key, Clone(value));
}
}
else
{
if (key_type.IsPrimitive || key_type.IsValueType || key_type == typeof(String))
{
dict_clone_obj.Add(Clone(key), value);
}
else
{
dict_clone_obj.Add(Clone(key), Clone(value));
}
}

}
return;
}
}

FieldInfo[] fields = type.GetFields();
foreach (FieldInfo field in fields)
{
if (field.IsStatic)
{
continue;
}
if (field.FieldType.IsPrimitive || field.FieldType.IsValueType || field.FieldType == typeof(String))
{
field.SetValue(dst, field.GetValue(src));
}
else
{
object field_value = field.GetValue(src);
if (field_value != null)
{
field.SetValue(dst, Clone(field_value));
}
}
}
}
}

总体思路就是利用反射拿到字段(Field),然后拷贝字段。