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. webapi下的web请求

    先看webapi提供的服务: [HttpPost] public ResultBaseModel SiteList(SiteModel param) { ResultBaseModel resultM ...

  2. unity集成openinstall流程

    目的 1.Unity集成openinstall sdk? 最近在使用一个叫openinstall的SDK,通过它实现免填邀请码的功能,集成到unity游戏开发中.对App安装流程的优化,尤其是免填写邀 ...

  3. log4net应用实践(一)

          1.背景 log4net库是Apache log4j框架在Microsoft .NET平台的实现,是一个帮助程序员将日志信息输出到各种目标(控制台.文件.数据库等)的工具.它是.Net下一 ...

  4. Infinite Fraction Path HDU 6223 2017沈阳区域赛G题题解

    题意:给你一个字符串s,找到满足条件(s[i]的下一个字符是s[(i*i+1)%n])的最大字典序的长度为n的串. 思路:类似后缀数组,每次倍增来对以i开头的字符串排序,复杂度O(nlogn).代码很 ...

  5. Xshell提示缺失mfc110.dll

    xshell  应用程序无法正常启动0xc000007b    下载 DirectX修复工具_3.3 Xshell 缺少 mfc110.dll     https://www.microsoft.co ...

  6. linux修改时区

    Linux修改时区 原创作品,允许转载,转载时请务必以超链接形式标明文章 原始出处 .作者信息和本声明.否则将追究法律责任 CentOS6: 查看以前的时区: [root@localhost mysq ...

  7. Angular开发实践(二):HRM运行机制

    引言 在angular-start项目中启用了模块热替换(HMR - Hot Module Replacement)功能,关于如何在angular-cli启用HRM,请查看HRM配置 那HMR是个什么 ...

  8. 跨域的另一种解决方案CORS(CrossOrigin Resource Sharing)跨域资源共享

    在我们日常的项目开发时使用AJAX,传统的Ajax请求只能获取在同一个域名下面的资源,但是HTML5打破了这个限制,允许Ajax发起跨域的请求.浏览器是可以发起跨域请求的,比如你可以外链一个外域的图片 ...

  9. hibernate的一级和二级缓存

    一级缓存就是Session级别的缓存,close后就没了. 二级缓存就是SessionFactory级别的缓存,全局缓存,要配置其他插件. 什么样的数据适合存放到第二级缓存中? 1.很少被修改的数据 ...

  10. echarts对每个data[i]的图片添加点击事件

    1.综述:以饼图为例,只需要对echarts对象option添加以下几行代码即可 //添加点击事件(单击),还有其他鼠标事件和键盘事件等等 myChart1.on("click", ...