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. Xamarin改变移动开发的五个理由

    企业开发者不能简单的抛弃现有的桌面和Web应用,然而又不得不忙着创建各种各样的应用,没有太多的预算来开发移动版本,尤其是原生版本. 采用Xamarin,C#开发人员可以使用一份基础代码创建桌面版和移动 ...

  2. NYOJ一种排序

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

  3. VirboxLM许可管理平台,一站式软件保护解决方案

    安全,易用,灵活 轻松解决开发者软件版权保护难题 Virbox LM为企业提供安全易用的软件保护管理平台,实现高安全强度的软件防护,防止盗版及逆向工程.实现便捷.安全的软件授权,包括创建灵活的许可模式 ...

  4. linux学习之路--(三)文件系统

    一.文件系统 rootfs:根文件系统 FHS:linux /boot:系统启动相关的文件,如内核.initrd,grub(bootloader) /dev:设备文件:不存储内容,就是个访问入口 块设 ...

  5. leetCode:461 汉明距离

    汉明距离 两个整数之间的汉明距离指的是这两个数字对应二进制位不同的位置的数目. 给出两个整数 x 和 y,计算它们之间的汉明距离. 思路: 当看到"对应二进制位不同的位置的数目"这 ...

  6. K-Means 聚类

    机器学习中的算法主要分为两类,一类是监督学习,监督学习顾名思义就是在学习的过程中有人监督,即对于每一个训练样本,有对应的标记指明它的类型.如识别算法的训练集中猫的图片,在训练之前会人工打上标签,告诉电 ...

  7. Java获取键盘输入

    方法一:在控制台接收字符串并将其打印出来,使用BufferedReader和InputStreamReader类实现 import java.io.*; public class Demo { pub ...

  8. [poj2585]Window Pains_拓扑排序

    Window Pains poj-2585 题目大意:给出一个4*4的方格表,由9种数字组成.其中,每一种数字只会出现在特定的位置,后出现的数字会覆盖之前在当前方格表内出现的.询问当前给出的方格表是否 ...

  9. 设计模式之迭代器模式详解(foreach的精髓)

    作者:zuoxiaolong8810(左潇龙),转载请注明出处,特别说明:本博文来自博主原博客,为保证新博客中博文的完整性,特复制到此留存,如需转载请注明新博客地址即可. 各位好,很久没以LZ的身份和 ...

  10. LeetCode算法一题型一以及解答。

    题目: 给定一个整数数列,找出其中和为特定值的那两个数. 你可以假设每个输入都只会有一种答案,同样的元素不能被重用. 分析: 普遍方法是直接遍历两遍数组,第一遍用target-nums[i],第二遍找 ...