惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

H
Help Net Security
J
Java Code Geeks
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
H
Hackread – Cybersecurity News, Data Breaches, AI and More
V
Visual Studio Blog
G
Google Developers Blog
V
V2EX
The Register - Security
The Register - Security
博客园 - 三生石上(FineUI控件)
云风的 BLOG
云风的 BLOG
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
CTFtime.org: upcoming CTF events
CTFtime.org: upcoming CTF events
博客园_首页
S
SegmentFault 最新的问题
博客园 - Franky
Martin Fowler
Martin Fowler
Stack Overflow Blog
Stack Overflow Blog
A
About on SuperTechFans
人人都是产品经理
人人都是产品经理
aimingoo的专栏
aimingoo的专栏
罗磊的独立博客
C
Check Point Blog
MyScale Blog
MyScale Blog
T
The Blog of Author Tim Ferriss
MongoDB | Blog
MongoDB | Blog
The GitHub Blog
The GitHub Blog
Last Week in AI
Last Week in AI
Microsoft Azure Blog
Microsoft Azure Blog
IT之家
IT之家
F
Fortinet All Blogs
Jina AI
Jina AI
P
Proofpoint News Feed
freeCodeCamp Programming Tutorials: Python, JavaScript, Git & More
阮一峰的网络日志
阮一峰的网络日志
B
Blog
L
LangChain Blog
月光博客
月光博客
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
宝玉的分享
宝玉的分享
博客园 - 【当耐特】
T
Tailwind CSS Blog
酷 壳 – CoolShell
酷 壳 – CoolShell
Microsoft Security Blog
Microsoft Security Blog
WordPress大学
WordPress大学
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
B
Blog RSS Feed
博客园 - 聂微东
Hugging Face - Blog
Hugging Face - Blog
M
MIT News - Artificial intelligence
GbyAI
GbyAI

博客园 - egmkang

配眼镜最佳实践 [Python]解密pyc文件 C# Protobuf如何做到0分配内存的序列化/反序列化(2) CPU实现原子操作的原理 Flash----一种VirtualActor模式的分布式有状态系统原型 [投资]对价值投资新的理解 通过Consul Raft库打造自己的分布式系统 Dapr实现分布式有状态服务的细节 [06] 优化C#服务器的思路和工具的使用 [05] 通过P/Invoke加速C#程序 [04] C# Alloc Free编程之实践 [03] C# Alloc Free编程 [02] 多线程逻辑编程 [01] C#网络编程的最佳实践 C# Protobuf如何做到0分配内存的序列化 最近很火的namebase羊毛, 手把手教你怎么薅 DotNetty发送请求的最佳实践 C# protobuf自动更新cs文件 多读少写场景下多线程锁冲突的降低
C#如何正确的做深拷贝
egmkang · 2020-04-13 · via 博客园 - egmkang

估计很多人在网上看到各种各样的DeepClone实现, 例如:

1. 通过BinaryFormatter进行二进制序列化

 这玩意儿序列化出来的东西还带namespace类型, 尺寸非常大, 调试一下就知道极其不靠谱

 有些人又开始动歪脑筋了, 说我搞一个JSON序列化, 或者BSON序列化可不可以

2. JSON/BSON序列化

 本质问题还是一样的, Object => byte[] => Object, 中间产生的垃圾对象太多, 尤其是Stream那些

所以, 我们需要思考DeepClone的本质是啥!

如果现在有一个类A, 你自己手写一个Clone函数, 那么是不是可以做到效率最高? 答案是显然的, 我知道有什么成员, new一个对象分别赋值就行了.

但是如果这个类A成天改, 维护的成本就比较高昂, 万一哪天忘了改, 就会出现一些奇妙的BUG.

所以, 类A的Clone函数, 是一个重复性的工作.

所有重复性的工作, 都可以通过代码生成来搞.

那么会有很多代码生成的答案:

3. 写一个DSL编译器

    不要嘲笑这种方式, protobuf在C++的实现里面, 就有一个原型工厂, 做的是类似的事情. C++里面没有反射只能通过这种方式, 只要把这些脏活累活交给编译器就可以了.

    唯一不同的是, 这是编译前代码生成.

4. 通过Emit生成代码

    我们都知道.NET平台有比较强的动态性, 可以动态的load/unload assembly. 甚至还可以动态的构造assembly和class和function.

    所以, 我们可以对类A生成一个Clone函数, 通过反射获取到其成员, 然后动态生成其Clone函数, 就相当于手写的代码, 效率可以做到最高.

    然后可以把生成的函数保存起来. JIT也能对其进行优化.

    具体实现可以参考: DeepCloner

   

     去他的GITHUB上面瞄一眼就知道是最佳姿势.

5. 通过ExpressionTree生成代码

    表达式树也可以生成代码, 具体可以 参考一下

  https://www.codeproject.com/articles/1111658/fast-deep-copy-by-expression-trees-c-sharp

    https://stackoverflow.com/questions/23229882/deep-clone-with-expression-new-and-expression-trees

开头那些序列化, 一看就不靠谱, 不知道为啥流传了这么多年