ITPub博客

首页 > 数据库 > 数据库开发技术 > C#/.NET Core基础 - 深拷贝的五大类实现方式

C#/.NET Core基础 - 深拷贝的五大类实现方式

原创 数据库开发技术 作者:后端Q 时间:2024-10-18 00:00:00 0 删除 编辑

在C#和.NET Core开发中,深拷贝是一个常见的需求。深拷贝与浅拷贝不同,深拷贝会递归地复制对象的所有字段,包括嵌套的对象。本文将介绍C#中实现深拷贝的五大类方法及相应的示例代码。

1. 使用序列化与反序列化

序列化与反序列化是一种常用的实现深拷贝的方法。通过将对象序列化为字节流,然后再反序列化回对象,可以实现对象的深拷贝。

示例代码(二进制序列化):

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }

    public object Clone()
    {
        using (MemoryStream stream = new MemoryStream())
        {
            BinaryFormatter formatter = new BinaryFormatter();
            formatter.Serialize(stream, this);
            stream.Seek(0, SeekOrigin.Begin);
            return formatter.Deserialize(stream);
        }
    }
}

[Serializable]
public class Department
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Department = new Department { Name = "Computer Science" }
        };

        Student student2 = (Student)student1.Clone();
        student2.Department.Name = "Mathematics";

        Console.WriteLine($"Student1 Department: {student1.Department.Name}"); // Output: Student1 Department: Computer Science
        Console.WriteLine($"Student2 Department: {student2.Department.Name}"); // Output: Student2 Department: Mathematics
    }
}

2. 使用反射

反射是另一种实现深拷贝的方法。通过递归地复制对象的所有字段,可以实现深拷贝。

示例代码(使用反射):

using System;
using System.Reflection;

public class DeepCloner
{
    public static T DeepCopy<T>(T obj)
    {
        if (obj is string || obj.GetType().IsValueType) return obj;

        object retval = Activator.CreateInstance(obj.GetType());

        FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance);
        foreach (FieldInfo field in fields)
        {
            field.SetValue(retval, DeepCopy(field.GetValue(obj)));
        }

        return (T)retval;
    }
}

public class Program
{
    public static void Main()
    {
        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Department = new Department { Name = "Computer Science" }
        };

        Student student2 = DeepCloner.DeepCopy(student1);
        student2.Department.Name = "Mathematics";

        Console.WriteLine($"Student1 Department: {student1.Department.Name}"); // Output: Student1 Department: Computer Science
        Console.WriteLine($"Student2 Department: {student2.Department.Name}"); // Output: Student2 Department: Mathematics
    }
}

3. 使用JSON序列化与反序列化

JSON序列化与反序列化也是一种常用的实现深拷贝的方法。通过将对象序列化为JSON字符串,然后再反序列化回对象,可以实现对象的深拷贝。

示例代码(使用Newtonsoft.Json):

using System;
using Newtonsoft.Json;

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}

public class Department
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Department = new Department { Name = "Computer Science" }
        };

        string json = JsonConvert.SerializeObject(student1);
        Student student2 = JsonConvert.DeserializeObject<Student>(json);
        student2.Department.Name = "Mathematics";

        Console.WriteLine($"Student1 Department: {student1.Department.Name}"); // Output: Student1 Department: Computer Science
        Console.WriteLine($"Student2 Department: {student2.Department.Name}"); // Output: Student2 Department: Mathematics
    }
}

4. 使用XML序列化与反序列化

与JSON类似,XML序列化与反序列化也是一种实现深拷贝的方法。

示例代码(使用XmlSerializer):

using System;
using System.IO;
using System.Xml.Serialization;

[Serializable]
public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}

[Serializable]
public class Department
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Department = new Department { Name = "Computer Science" }
        };

        string xml;
        using (StringWriter stringWriter = new StringWriter())
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));
            xmlSerializer.Serialize(stringWriter, student1);
            xml = stringWriter.ToString();
        }

        Student student2;
        using (StringReader stringReader = new StringReader(xml))
        {
            XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));
            student2 = (Student)xmlSerializer.Deserialize(stringReader);
        }

        student2.Department.Name = "Mathematics";

        Console.WriteLine($"Student1 Department: {student1.Department.Name}"); // Output: Student1 Department: Computer Science
        Console.WriteLine($"Student2 Department: {student2.Department.Name}"); // Output: Student2 Department: Mathematics
    }
}

5. 使用第三方库

有许多第三方库提供了深拷贝的功能,如AutoMapper、DeepCloner等。

示例代码(使用AutoMapper):

using System;
using AutoMapper;

public class Student
{
    public string Name { get; set; }
    public int Age { get; set; }
    public Department Department { get; set; }
}

public class Department
{
    public string Name { get; set; }
}

public class Program
{
    public static void Main()
    {
        MapperConfiguration config = new MapperConfiguration(cfg =>
        {
            cfg.CreateMap<Student, Student>();
            cfg.CreateMap<Department, Department>();
        });

        IMapper mapper = config.CreateMapper();

        Student student1 = new Student
        {
            Name = "Alice",
            Age = 20,
            Department = new Department { Name = "Computer Science" }
        };

        Student student2 = mapper.Map<Student>(student1);
        student2.Department.Name = "Mathematics";

        Console.WriteLine($"Student1 Department: {student1.Department.Name}"); // Output: Student1 Department: Computer Science
        Console.WriteLine($"Student2 Department: {student2.Department.Name}"); // Output: Student2 Department: Mathematics
    }
}

总结

在C#和.NET Core开发中,深拷贝是一个常见的需求。本文介绍了五种实现深拷贝的方法,包括使用序列化与反序列化、反射、JSON序列化与反序列化、XML序列化与反序列化以及第三方库。每种方法都有其适用场景和优缺点,开发者可以根据具体需求选择合适的方法。


原文作者:后端Q;如有侵权,请联系管理员删除。

请登录后发表评论 登录
全部评论

注册时间:2023-01-22

  • 博文量
    1540
  • 访问量
    726681