C#使用反射(Reflection)实现深复制与浅复制

原文路径:https://blog.csdn.net/qq_28839293/article/details/79487294

1、浅复制:

class Program
{
    public static void Main(string[] args)
    {
        var classA1 = new ClassA
        {
            a = 1,
            b = "haha",
            d = new ClassB{ c ="haha" }
        };

        var classA2 = (ClassA)classA1.Clone();

        classA2.b = "xixi";
        classA2.d.c = "xixi";

        Console.WriteLine("classA1.b=" + classA1.b + "\nclassA2.b=" + classA2.b);
        Console.WriteLine("classA1.d.c=" + classA1.d.c + "\nclassA2.d.c=" + classA2.d.c);
    }
}

public class ClassA : ICloneable
{
    public int a;

    public string b;

    public ClassB d;


    public object Clone()
    {
        object obj = new ClassA();
        //字段
        FieldInfo[] fields = typeof(ClassA).GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        for (int i = 0; i < fields.Length; i++)
        {
            FieldInfo field = fields[i];
            field.SetValue(obj, field.GetValue(this));
        }
        //属性
        PropertyInfo[] properties = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        for (int i = 0; i < properties.Length; i++)
        {
            PropertyInfo property = properties[i];
            property.SetValue(obj, property.GetValue(this));
        }
        return obj;
    }
}

public class ClassB
{
    public string c;
}

2、深度复制:使用反射进行深复制时,若碰到字段或属性为引用类型,则需要递归调用

public static object DeepClone(Object obj)
{
    Type type = obj.GetType();
    //对于没有公共无参构造函数的类型此处会报错
    object returnObj = Activator.CreateInstance(type);
    FieldInfo[] fields = type.GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    for (int i = 0; i < fields.Length; i++)
    {
        FieldInfo field = fields[i];
        var fieldValue = field.GetValue(obj);
        ///值类型,字符串,枚举类型直接把值复制,不存在浅拷贝
        if (fieldValue.GetType().IsValueType || fieldValue.GetType().Equals(typeof(System.String)) || fieldValue.GetType().IsEnum)
        {
            field.SetValue(returnObj, fieldValue);
        }
        else
        {
            field.SetValue(returnObj, DeepClone(fieldValue));
        }
    }
    //属性
    PropertyInfo[] properties = typeof(ClassA).GetProperties(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
    for (int i = 0; i < properties.Length; i++)
    {
        PropertyInfo property = properties[i];
        var propertyValue = property.GetValue(obj);
        if (propertyValue.GetType().IsValueType || propertyValue.GetType().Equals(typeof(System.String)) || propertyValue.GetType().IsEnum)
        {
            property.SetValue(returnObj, propertyValue);
        }
        else
        {
            property.SetValue(returnObj, DeepClone(propertyValue));
        }
    }

    return returnObj;
}

1.这里我没再使用ICloneable中的clone方法,而是单独写了一个静态方法来实现(因为涉及到递归) 
2.对于没有公共无参构造函数的类型,该方法不适用,代码中也做了注解 
3.对于浅复制与深复制这类操作,最好是写成工具类的形式,而不是去修改原有的类

 

转载于:https://www.cnblogs.com/MartinSun123/p/9345649.html

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
C#中,要实现类的复制,你可以使用以下几种方式: 1. 使用序列化和反序列化:使用BinaryFormatter或JsonSerializer等序列化器,将对象序列化为字节流或JSON字符串,然后再通过反序列化操作将其转换回新的对象。这种方式会创建一个完全独立的对象副本。 ```csharp using System.IO; using System.Runtime.Serialization.Formatters.Binary; using System.Runtime.Serialization.Json; // 使用BinaryFormatter进行复制 public static T DeepCopy<T>(T obj) { using (MemoryStream memoryStream = new MemoryStream()) { BinaryFormatter formatter = new BinaryFormatter(); formatter.Serialize(memoryStream, obj); memoryStream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(memoryStream); } } // 使用JsonSerializer进行复制 public static T DeepCopyJson<T>(T obj) { using (MemoryStream memoryStream = new MemoryStream()) { DataContractJsonSerializer serializer = new DataContractJsonSerializer(typeof(T)); serializer.WriteObject(memoryStream, obj); memoryStream.Position = 0; return (T)serializer.ReadObject(memoryStream); } } ``` 2. 实现ICloneable接口:让需要进行复制的类实现ICloneable接口,并在Clone方法中实现属性的逐个复制使用其他方式创建新的对象。 ```csharp public class MyClass : ICloneable { public int MyProperty { get; set; } public object Clone() { return new MyClass { MyProperty = this.MyProperty }; } } ``` 然后可以使用Clone方法进行复制: ```csharp MyClass original = new MyClass { MyProperty = 42 }; MyClass clone = (MyClass)original.Clone(); ``` 3. 使用第三方库:还可以使用一些第三方库,如AutoMapper、DeepClone等,它们提供了更高级的复制功能,可以自动处理对象之间的关联关系和复杂结构。 以上是实现类的复制的几种常见方式,你可以根据具体情况选择适合的方法。需要注意的是,如果类中包含引用类型的成员变量,你可能需要对这些成员变量也进行复制,以确保实现完全的复制

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值