反射拷贝相互耦合的对象, 容易死循环,借助chatgpt(真的牛),通过字典实现深拷贝。
using System.Reflection;
namespace test_01
{
public class DeepCopy
{
public static T DeepCopyObject<T>(T obj) where T : class
{
if (obj == null) return null;
Dictionary<object, object> copiedObjects = new Dictionary<object, object>();
return DeepCopyObject(obj, copiedObjects) as T;
}
public static object DeepCopyObject(object obj, Dictionary<object, object> copiedObjects)
{
if (obj == null) return null;
Type type = obj.GetType();
if (copiedObjects.ContainsKey(obj))
{
// 如果已经拷贝过该对象,直接返回拷贝结果
return copiedObjects[obj];
}
object copy = Activator.CreateInstance(type);
copiedObjects[obj] = copy;
// 拷贝字段
FieldInfo[] fields = type.GetFields(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (FieldInfo field in fields)
{
object fieldValue = field.GetValue(obj);
if (fieldValue == null) continue;
Type fieldType = field.FieldType;
if (fieldType.IsValueType || fieldType == typeof(string))
{
field.SetValue(copy, fieldValue);
}
else if (fieldType.IsArray)
{
Type elementType = fieldType.GetElementType();
if (elementType.IsValueType || elementType == typeof(string))
{
// 如果是值类型数组或字符串数组,直接复制
field.SetValue(copy, fieldValue);
}
else
{
// 如果是引用类型数组,递归进行深拷贝
Array array = fieldValue as Array;
Array arrayCopy = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
{
object elementCopy = DeepCopyObject(array.GetValue(i), copiedObjects);
arrayCopy.SetValue(elementCopy, i);
}
field.SetValue(copy, arrayCopy);
}
}
else
{
// 如果是引用类型字段,递归进行深拷贝
object fieldCopy = DeepCopyObject(fieldValue, copiedObjects);
field.SetValue(copy, fieldCopy);
}
}
// 拷贝属性
PropertyInfo[] properties = type.GetProperties(BindingFlags.NonPublic | BindingFlags.Public | BindingFlags.Instance | BindingFlags.DeclaredOnly);
foreach (PropertyInfo property in properties)
{
if (!property.CanWrite) continue;
object propertyValue = property.GetValue(obj);
if (propertyValue == null) continue;
Type propertyType = property.PropertyType;
if (propertyType.IsValueType || propertyType == typeof(string))
{
property.SetValue(copy, propertyValue);
}
else if (propertyType.IsArray)
{
Type elementType = propertyType.GetElementType();
if (elementType.IsValueType || elementType == typeof(string))
{
// 如果是值类型数组或字符串数组,直接复制
property.SetValue(copy, propertyValue);
}
else
{
// 如果是引用类型数组,递归进行深拷贝
Array array = propertyValue as Array;
Array arrayCopy = Array.CreateInstance(elementType, array.Length);
for (int i = 0; i < array.Length; i++)
{
object elementCopy = DeepCopyObject(array.GetValue(i), copiedObjects);
arrayCopy.SetValue(elementCopy, i);
}
property.SetValue(copy, arrayCopy);
}
}
else
{
// 如果是引用类型属性,递归进行深拷贝
object propertyCopy = DeepCopyObject(propertyValue, copiedObjects);
property.SetValue(copy, propertyCopy);
}
}
return copy;
}
}
public class Yin
{
public int m_age = 10;
public string m_name = "lili";
public Yang yang;
public Yin()
{
}
public Yin(int age, string name)
{
m_age = age;
m_name = name;
}
}
public class Yang
{
public int m_age = 20;
public string m_name = "huahua";
public Yin yin;
public Yang()
{
}
public Yang(int age, string name)
{
m_age = age;
m_name = name;
}
}
class Program
{
static void Main(string[] args)
{
Yin yin = new Yin(20, "yin");
Yang yang = new Yang(30, "yang");
yang.yin = yin;
yin.yang = yang;
Yang yang1 = DeepCopy.DeepCopyObject(yang);
Console.WriteLine(yang.yin.m_name);
Console.ReadLine();
}
}
}