c#基于反射深拷贝相互耦合对象

文章介绍了如何利用C#的反射和字典数据结构来避免对象拷贝时的循环引用问题,实现深拷贝。通过遍历对象的字段和属性,递归处理引用类型,确保复杂对象结构的完整复制。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

反射拷贝相互耦合的对象, 容易死循环,借助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();
        }
    }
}
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值