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. jqgrid 单元格引入时间datepicker控件

    简述原理:引入jquery-ui插件,设置好表格所需的字段变量以及字段属性1.设置colName与colModel colNames: ['过期时间''] colModel:[{       name ...

  2. redis笔记总结之redis数据类型及常用命令

    三.常用命令 3.1 字符串类型(string) 字符串类型是Redis中最基本的数据类型,一个字符串类型的键允许存储的数据的最大容量为512MB. 3.1.1 赋值与取值: SET key valu ...

  3. C#封装程序集属性方法注释说明

    一.使用封装程序集好处: 在很多分布式应用程序开发中,针对每一种功能可能条用的接口不一样,往往习惯将需要被调用的接口,封装成DLL给调用方应用后使用,这样既规范了调用的方式,又避免了调用出现参数请求方 ...

  4. NYOJ一种排序

    //最重要的收获就是懂得了,还可以调用库函数直接对结构体进行排序sort(const void *,const void *,cmp) /* bool cmp(rect c,rect d) { if( ...

  5. shell常见脚本30例

    shell常见脚本30例 author:headsen chen  2017-10-19  10:12:12 本文原素材出自网上,特此申明.有些地方加入我自己的改动 常见的30例shell脚本 1.用 ...

  6. 3.21电脑重装“operation not found system ”和xp分盘”分配表有标记为已使用的未用簇”

    问题一.是用光盘重装系统后重启,提示operation not found system ①考虑是系统问题,没装好,还是引导文件丢失;换新盘装,若还是一样; ②分析认为是分区问题,必须是活动分区+主分 ...

  7. [Apio2010] 巡逻

    Description Input 第一行包含两个整数 n, K(1 ≤ K ≤ 2).接下来 n – 1行,每行两个整数 a, b, 表示村庄a与b之间有一条道路(1 ≤ a, b ≤ n). Ou ...

  8. 学习资料分享(Java第一行代码视频)<susmote.com>

    17年买了一本书,第一行代码(JAVA),李兴华编写的. 一开始我是按照书本一页一页的啃,一个点一个点的去学,虽然当时学的有些枯燥,但里面的知识点大部分还是弄的懂,只是一次偶然,因为有点质疑书上写的( ...

  9. scanf()中的%c 不能正常输入的问题

    #include <stdio.h> int main() { char a; int b; scanf("%d",&b); scanf("%c&qu ...

  10. 将 Shiro 作为应用的权限基础 一:shiro的整体架构

    将 Shiro 作为应用的权限基础 一:shiro的整体架构 近来在做一个重量级的项目,其中权限.日志.报表.工作量由我负责,工作量还是蛮大的,不过想那么多干嘛,做就是了. 这段时间,接触的东西挺多, ...