public static class Tools
{
//利用 BinaryFormatter 实现深拷贝
public static T DeepCopyByBinary<T>(this T obj)
{
T t = default(T);
IFormatter formatter = new BinaryFormatter();
using (MemoryStream ms = new MemoryStream())
{
formatter.Serialize(ms, obj);
ms.Seek(, SeekOrigin.Begin);
t = (T)formatter.Deserialize(ms);
}
return t;
} //利用 XmlSerializer 实现深拷贝
public static T DeepCopyByXml<T>(this T obj)
{
T t = default(T);
XmlSerializer xmlserialize = new XmlSerializer(typeof(T));
using (MemoryStream ms = new MemoryStream())
{
xmlserialize.Serialize(ms, obj);
ms.Seek(, SeekOrigin.Begin);
t = (T)xmlserialize.Deserialize(ms);
}
return t;
} //利用反射实现深拷贝
public static T DeepCopyByReflection<T>(this T tSource)
{
T tResult = Activator.CreateInstance<T>();
Type sourceType = typeof(T);
Type resultType = typeof(T);
var sourcePros = sourceType.GetProperties();
foreach (var pro in sourcePros)
{
var sourceProValue = pro.GetValue(tSource);
var resultPro = resultType.GetProperty(pro.Name);
resultPro.SetValue(tResult, sourceProValue);
}
return tResult;
}
}
            Person p1 = new Person { Id = , Name = "wjire" };
Stopwatch sw1 = new Stopwatch();
sw1.Start();
for (int i = ; i < ; i++)
{
Person p2 = p1.DeepCopyByBinary();
}
sw1.Stop();
Console.WriteLine($"DeepCopyByBinary 共耗时 {sw1.ElapsedMilliseconds} 毫秒"); Stopwatch sw2 = new Stopwatch();
sw2.Start();
for (int i = ; i < ; i++)
{
Person p2 = p1.DeepCopyByXml();
}
sw2.Stop();
Console.WriteLine($"DeepCopyByXml 共耗时 {sw2.ElapsedMilliseconds} 毫秒"); Stopwatch sw3 = new Stopwatch();
sw3.Start();
for (int i = ; i < ; i++)
{
Person p2 = p1.DeepCopyByReflection();
}
sw3.Stop();
Console.WriteLine($"DeepCopyByReflection 共耗时 {sw3.ElapsedMilliseconds} 毫秒"); //利用 json.net 实现深拷贝
Stopwatch sw4 = new Stopwatch();
sw4.Start();
for (int i = ; i < ; i++)
{
Person p2 = JsonConvert.DeserializeObject<Person>(JsonConvert.SerializeObject(p1));
}
sw4.Stop();
Console.WriteLine($"Newtonsoft.Json 共耗时 {sw4.ElapsedMilliseconds} 毫秒");

运行结果:

反射最快!!

    class Program
{
static void Main(string[] args)
{
Person p1 = new Person()
{
Id = ,
Age = ,
Name = "wjire"
}; Expression<Func<Person, Person>> exp1 = p => new Person() { Id = p.Id, Name = p.Name, Age = p.Age };
var func1 = exp1.Compile();
Person p23 = func1(p1);
Console.WriteLine(p23.Id); Console.WriteLine("*****************************");
ParameterExpression parameterExpression = Expression.Parameter(p1.GetType(), "p"); // 创造了 lambda表达式中的入参: p
Console.WriteLine(parameterExpression); List<MemberBinding> memberBindingList = new List<MemberBinding>();
foreach (PropertyInfo pro in p1.GetType().GetProperties())
{
if (!pro.CanWrite)
{
continue;
}
MemberExpression property = Expression.Property(parameterExpression, pro.Name);
Console.WriteLine(property);// p.Id,p.Name,p.Age MemberBinding memberBinding = Expression.Bind(pro, property);
Console.WriteLine(memberBinding);// p=p.Id,p=p.Name,p=p.Age memberBindingList.Add(memberBinding);
} var rr = Expression.New(p1.GetType().GetConstructor(new Type[] { typeof(int) }), Expression.Constant(default(int))); MemberInitExpression initExpression = Expression.MemberInit(rr, memberBindingList);
Console.WriteLine(initExpression);// new Person { Id = p.Id, Name = p.Name, Age = p.Age } Expression<Func<Person, Person>> exp = Expression.Lambda<Func<Person, Person>>(initExpression, parameterExpression);
Console.WriteLine(exp);// p => new Person { Id = p.Id, Name = p.Name, Age = p.Age } Func<Person, Person> func = exp.Compile();
Person p2 = func(p1); Console.WriteLine(p2.Name);
Console.WriteLine(p2.Id);
Console.WriteLine(p2.Age);
Console.ReadKey();
}
} internal class Person
{
public int Id { get; set; }
public string Name { get; set; } public int Age { get; set; } public Person(int id)
{
this.Id = id;
}
}

c# 几种深拷贝方式的比较的更多相关文章

  1. 一种c#深拷贝方式完胜java深拷贝(实现上的对比)

    楼主是一名asp.net攻城狮,最近经常跑java组客串帮忙开发,所以最近对java的一些基础知识特别上心.却遇到需要将一个对象深拷贝出来做其他事情,而原对象保持原有状态的情况.(实在是不想自己new ...

  2. Web APi之认证(Authentication)两种实现方式【二】(十三)

    前言 上一节我们详细讲解了认证及其基本信息,这一节我们通过两种不同方式来实现认证,并且分析如何合理的利用这两种方式,文中涉及到的基础知识,请参看上一篇文中,就不再叙述废话. 序言 对于所谓的认证说到底 ...

  3. CSS垂直居中的11种实现方式

    今天是邓呆呆球衣退役的日子,在这个颇具纪念意义的日子里我写下自己的第一篇博客,还望前辈们多多提携,多多指教! 接下来,就进入正文,来说说关于垂直居中的事.(以下这11种垂直居中的实现方式均为笔者在日常 ...

  4. Android中BroadcastReceiver的两种注册方式(静态和动态)详解

    今天我们一起来探讨下安卓中BroadcastReceiver组件以及详细分析下它的两种注册方式. BroadcastReceiver也就是"广播接收者"的意思,顾名思义,它就是用来 ...

  5. Android中Fragment与Activity之间的交互(两种实现方式)

    (未给Fragment的布局设置BackGound) 之前关于Android中Fragment的概念以及创建方式,我专门写了一篇博文<Android中Fragment的两种创建方式>,就如 ...

  6. Android开发之基本控件和详解四种布局方式

    Android中的控件的使用方式和iOS中控件的使用方式基本相同,都是事件驱动.给控件添加事件也有接口回调和委托代理的方式.今天这篇博客就总结一下Android中常用的基本控件以及布局方式.说到布局方 ...

  7. 通过三个DEMO学会SignalR的三种实现方式

    一.理解SignalR ASP .NET SignalR 是一个ASP .NET 下的类库,可以在ASP .NET 的Web项目中实现实时通信(即:客户端(Web页面)和服务器端可以互相实时的通知消息 ...

  8. Hive metastore三种配置方式

    http://blog.csdn.net/reesun/article/details/8556078 Hive的meta数据支持以下三种存储方式,其中两种属于本地存储,一种为远端存储.远端存储比较适 ...

  9. Hive的三种安装方式(内嵌模式,本地模式远程模式)

    一.安装模式介绍:     Hive官网上介绍了Hive的3种安装方式,分别对应不同的应用场景.     1.内嵌模式(元数据保村在内嵌的derby种,允许一个会话链接,尝试多个会话链接时会报错)   ...

随机推荐

  1. AI行业需要什么样的人才

    自AI人工智能诞生以来,它的领域逐步扩大,技术层面也越来越多样化,投身于该领域的人才也越来越多,那么AI行业到底需要什么样的人才?我们应该如何定位自己,找到适合的领域?3月8日晚,在飞马网线上直播中, ...

  2. canvas 绘制图形

    canvas 绘制图形: 注意: canvas 的宽高设置在行内,否则会使画布(canvas)产生扭曲,绘图变形: <!DOCTYPE html> <html lang=" ...

  3. Effective Java 第三版——37. 使用EnumMap替代序数索引

    Tips <Effective Java, Third Edition>一书英文版已经出版,这本书的第二版想必很多人都读过,号称Java四大名著之一,不过第二版2009年出版,到现在已经将 ...

  4. 剑指Offer-链表中环的入口结点

    package LinkedList; import java.util.HashSet; /** * 链表中环的入口结点 * 一个链表中包含环,请找出该链表的环的入口结点. */ public cl ...

  5. 关于 BigDecimal处理float、double数据

    Big Decimal 在java中,对于float与double中的数据,总会因为精度问题而丢失数据的准确性,也就是说对于两者所处理的得到的值是无限接近于那个数,而并非一个精确数字,而对于电商中所涉 ...

  6. es6使用技巧

    ##1.通过参数默认值实现强制参数 ES6 的参数默认值只有在真正使用时才会求值.这可以让你强制确保提供参数: /** * Called if a parameter is missing and * ...

  7. 一次精疲力尽的改bug经历

    一.介绍 最近一直在做有关JavaScriptCore的技术需求,上周发现一个问题,当在JavaScriptCore在垃圾回收时,项目会有一定几率发生崩溃.崩溃发生时调用堆栈如下: 图1 调用堆栈 先 ...

  8. JVM内存管理概述与android内存泄露分析

    一.内存划分 将内存划分为六大部分,分别是PC寄存器.JAVA虚拟机栈.JAVA堆.方法区.运行时常量池以及本地方法栈. 1.PC寄存器(线程独有):全称是程序计数寄存器,它记载着每一个线程当前运行的 ...

  9. ConcurrentHashMap 源码分析

    ConcurrentHashMap 源码分析 1. 前言    终于到这个类了,其实在前面很过很多次这个类,因为这个类代码量比较大,并且涉及到并发的问题,还有一点就是这个代码有些真的晦涩,不好懂.前前 ...

  10. xilinx的quick boot(1) ——flash的一些内容

    xilinx的quick boot(1) --flash,quick boot配置文件,以及中间的一些联系xilinx 配置模式分为SPI,BPI.用过的spi外挂flash是N25Q./////// ...