NET 中深度拷贝一个对象

原理分析

在.NET 中,如果你想要深度拷贝一个对象,你可以使用序列化和反序列化的方式来实现。这种方式的好处是可以确保对象的所有属性都被正确地复制,包括那些不可见的属性。

以下是一个示例代码,展示了如何深度拷贝一个TreeList 对象:

csharp 复制代码
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;
public static T DeepClone<T>(T obj)
{
	using (var memoryStream = new MemoryStream())
	{
	    var binaryFormatter = new BinaryFormatter();
	    binaryFormatter.Serialize(memoryStream, obj);
	    memoryStream.Position = 0;
	    return (T)binaryFormatter.Deserialize(memoryStream);
	}
}

这段代码的工作原理是首先创建一个内存流(MemoryStream),然后使用二进制格式化器

(BinaryFormatter)将对象序列化到这个流中。

然后,将流的位置重置到开始,然后再次使用格式化器将对象从流中反序列化出来。这样,你就得到了一个新的对象,这个对象是原始对象的深度拷贝。

这段代码的使用方法如下:

csharp 复制代码
var originalTreeList = new TreeList();
// 设置originalTreeList 的属性...
var clonedTreeList = DeepClone(originalTreeList);

注意:这种方法只适用于标记为Serializable的对象。

如果你的TreeList 对象没有标记为Serializable,那么你需要手动创建一个新的TreeList 对象,并复制原始对象的所有属性。

具体demo

csharp 复制代码
```csharp 
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class TreeList
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Additional properties can be added here
}

public class Program
{
    public static void Main()
    {
        var originalTreeList = new TreeList
        {
            Id = 1,
            Name = "Original"
        };
        
        var clonedTreeList = DeepClone(originalTreeList);
        
        Console.WriteLine($"Original ID: {originalTreeList.Id}, Name: {originalTreeList.Name}");
        Console.WriteLine($"Cloned ID: {clonedTreeList.Id}, Name: {clonedTreeList.Name}");
    }

    public static T DeepClone<T>(T obj)
    {
        using (var memoryStream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(memoryStream, obj);
            memoryStream.Position = 0;
            return (T)formatter.Deserialize(memoryStream);
        }
    }
}
 
 ```using System;
using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;

[Serializable]
public class TreeList
{
    public int Id { get; set; }
    public string Name { get; set; }
    // Additional properties can be added here
}

public class Program
{
    public static void Main()
    {
        var originalTreeList = new TreeList
        {
            Id = 1,
            Name = "Original"
        };
        
        var clonedTreeList = DeepClone(originalTreeList);
        
        Console.WriteLine($"Original ID: {originalTreeList.Id}, Name: {originalTreeList.Name}");
        Console.WriteLine($"Cloned ID: {clonedTreeList.Id}, Name: {clonedTreeList.Name}");
    }

    public static T DeepClone<T>(T obj)
    {
        using (var memoryStream = new MemoryStream())
        {
            var formatter = new BinaryFormatter();
            formatter.Serialize(memoryStream, obj);
            memoryStream.Position = 0;
            return (T)formatter.Deserialize(memoryStream);
        }
    }
}

在这个示例中,我们首先定义了一个TreeList 类,并添加了两个属性:Id 和Name。然后,我们创建了一个TreeList 对象,并设置了它的属性。

接着,我们使用DeepClone 方法创建了一个新的TreeList 对象,这个新对象是原始对象的深度拷贝。最后,我们打印出了原始对象和复制对象的属性,以验证深度拷贝的正确性。

注意:TreeList 类需要被标记为Serializable,这样BinaryFormatter 才能正确地序列化和反序列化它。

相关推荐
开开心心就好1 小时前
批量提取PDF中的图片,直接导出原图
前端·javascript·支持向量机·智能手机·pdf·html·启发式算法
Setsuna_F_Seiei3 小时前
前端转型 Agent 开发 05 之 Agent Hooks 与 Checkpointer(让 Agent 从全自动转变人为可掌控)
前端·agent·ai编程
百万蹄蹄向前冲5 小时前
风扇转了一晚上MVP专家团翻车事故
前端·人工智能
默_笙5 小时前
🏛 给 AI 配一间办公室:Harness Engineering 六大模块与它的实现
前端·javascript
linux_cfan7 小时前
videojs v10 源代码系列解读:14 · 谓词守卫:在运行时安全地调用能力
前端·javascript·音视频
kyriewen7 小时前
我扒了 10,221 条 JD:腾讯技术岗 75% 在要 AI
前端·人工智能·ai编程
郑州光合科技余经理8 小时前
同城外卖小程序开发:下单成功后,后台导出能不能对上用户端状态
开发语言·前端·git·后端·uni-app·php·ai编程
IT_陈寒8 小时前
Vue的响应式让我熬到凌晨三点,原来漏了这个小细节
前端·人工智能·后端
Blanche15009 小时前
利用 RAG 为答疑机器人扩展知识范围
前端
天若有情6739 小时前
【纯前端小工具】公历生日转农历,批量查询每年农历生日对应的公历日期(GitHub Pages在线直接用)
前端·javascript·github pages·农历转换·lunisolar·网页小工具