c# 引用类型对象的深拷贝
c#中的对象大体分为值类型和引用类型,值类型大致包括 int, struct等,引用类型大致包括 自定义Class,object 等。string属于特殊的引用类型,不在本文的讨论之内。
值类型直接存储对象,而引用类型存储对象的地址,在对引用类型进行复制的时候,也只是复制对象的地址。
完全复制一个引用类型对象主要有几种方法:
1.添加一个Copy函数,进行拷贝(如果字段为引用类型,需要循环添加Copy函数,这样情况会变的十分复杂。)
namespace ConsoleApplication1
{
class User
{
public string Name { get; set; }
public string Sex { get; set; }
public House Home { get; set; }
public User Copy()
{
User newUser = (User)this.MemberwiseClone();
newUser.Home = this.Home.Copy();
return newUser;
}
}
class House
{
public string Address { get; set; }
public House Copy()
{
return (House)this.MemberwiseClone();
}
}
class Program
{
static void Main(string[] args)
{
User a = new User();
a.Name = "A";
a.Home = new House() { Address = "长江路" };
User b = a.Copy();
b.Name = "B";
b.Home.Address = "黄河路";
Console.WriteLine(a.Name);
Console.WriteLine(a.Home.Address);
Console.ReadLine();
}
}
}
2.利用序列化反序列化(对性能会有杀伤)
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Runtime.Serialization.Formatters.Binary;
using System.Text;
using System.Threading.Tasks; namespace Test
{
class Program
{
static void Main(string[] args)
{
Test t1 = new Test();
Console.WriteLine(t1.list.Count);
Test t2 = (Test)Clone(t1);
t2.list.Add("");
Console.WriteLine(t2.list.Count);
Console.WriteLine(t1.list.Count);
Console.ReadLine();
} public static object Clone(object obj)
{
BinaryFormatter bf = new BinaryFormatter();
MemoryStream ms = new MemoryStream();
bf.Serialize(ms, obj);
ms.Position = ;
return (bf.Deserialize(ms)); ;
}
} [Serializable]
public class Test
{
public List<string> list = new List<string>();
}
}
3.利用反射(测试了一个网上的接口可用,但是对性能杀伤和序列化反序列化相当,而且可能对代码混淆有一定影响。 https://www.cnblogs.com/zhili/p/DeepCopy.html)
最后附上微软文档:
https://docs.microsoft.com/zh-cn/dotnet/api/system.object.memberwiseclone?redirectedfrom=MSDN&view=netframework-4.7.2#System_Object_MemberwiseClone
c# 引用类型对象的深拷贝的更多相关文章
- C#系列——记一次业务需求:对象的深拷贝
这篇随笔着实在意料之外,主要是源于上周开发BS的一个业务,需要用到对象的深拷贝.说的直白一点,就是将对象内存分配区和引用完全拷贝一份新的.这种需求以前就遇到过,怎么解决的已经记不清了.这次趁着这个机会 ...
- JS 数组、对象的深拷贝
博客地址:https://ainyi.com/72 JavaScript 程序中,对于简单的数字.字符串可以通过 = 赋值拷贝 但是对于数组.对象.对象数组的拷贝,就有浅拷贝和深拷贝之分 浅拷贝就是当 ...
- 谈谈java中对象的深拷贝与浅拷贝
知识点:java中关于Object.clone方法,对象的深拷贝与浅拷贝 引言: 在一些场景中,我们需要获取到一个对象的拷贝,这时候就可以用java中的Object.clone方法进行对象的复制,得到 ...
- 探究JS中对象的深拷贝和浅拷贝
深拷贝和浅拷贝的区别 在讲深拷贝和浅拷贝的区别之前,回想一下我们平时拷贝一个对象时是怎么操作的?是不是像这样? var testObj1 = {a: 1, b:2}, testObj2=testObj ...
- javascript学习总结之对象的深拷贝和浅拷贝
前言 最近在写ES6的文章的时候发现重复遇到关于javascript深拷贝和浅拷贝的问题,然后查找了一些资料,根据资料和自己的理解做了以下笔记,毕竟javascript关于深拷贝和浅拷贝的问题在一些面 ...
- C#对象的深拷贝与浅拷贝
转载自:http://blog.163.com/hr_msn/blog/static/21549405120132250396584/ 深拷贝是指源对象与拷贝对象互相独立,其中任何一个对象的改动都不会 ...
- AS3深拷贝数据对象(2)深拷贝VO对象
Topic:对于用户自定义的VO对象进行深拷贝,一种VO对象的某属性可能是另一种VO对象的实例. 方法1:通过传说中的“AS3隐藏特性——ByteArray.writeObject和readObjec ...
- Javascript delete 引用类型对象
很少使用javascript的delete,最近因为一个小bug发现删除引用类型对象的时候有一点不同.如下面例子: var testVar = { a : { test : 1 } }, test1 ...
- 使用JSON.parse(),JSON.stringify()实现对对象的深拷贝
根据不包含引用对象的普通数组深拷贝得到启发,不拷贝引用对象,拷贝一个字符串会新辟一个新的存储地址,这样就切断了引用对象的指针联系. 测试例子: var test={ a:"ss", ...
随机推荐
- [GO]结构体成员的使用:普通变量
package main import "fmt" func main() { type student struct { id int name string sex byte ...
- ubuntu创建wifi热点plasma-nm
第一步:安装 plasma-nm sudo apt-get install plasma-nm 第二步:启动程序 可以使用 Alt+F2 后,搜索 kde-nm-connection-editor 也 ...
- 三)EasyUI layout
参考文档 http://www.jeasyui.com/documentation/layout.php
- Android 内存优化[转]
一. Android的内存机制 Android的程序由Java语言编写,所以Android的内存管理与Java的内存管理相似.程序员通过new为对象分配内存,所有对象在java堆内分配空间:然而对象的 ...
- 使用GeoServer+OpenLayers发布和调用WMTS、Vector Tile矢量切片服务 | Publishing and Calling WMTS, Vector Tile Service Using GeoServer + OpenLayers
Web GIS系列: 1.搭建简易Web GIS网站:使用GeoServer+PostgreSQL+PostGIS+OpenLayers3 2.使用GeoServer+QGIS发布WMTS服务 3.使 ...
- Spring Cache介绍和使用
Spring Cache 缓存是实际工作中非经常常使用的一种提高性能的方法, 我们会在很多场景下来使用缓存. 本文通过一个简单的样例进行展开,通过对照我们原来的自己定义缓存和 spring 的基于凝视 ...
- Sweetkang 的机器学习实验室 (1)
前言 近年来,Machine Learning 在许多领域上已然取得了可喜的成就,非常火热.就我个人来讲,有意将业余 Sport Programming 的范围扩展一下,譬如 Topcoder Mar ...
- VC6.0 如何显示代码行号
VC6.0是一款比较经典.稳定的功能强大的IDE,目前也有很多人在使用.但美中不足的是它不能像其他IDE那样显示行号.这里需要用到一个插件VC6LineNumberAddin, 下载地址:http:/ ...
- Linux系统优化及状态监控
1.查看系统进程命令 top 进入后可按s 加时间,指定多长时间刷新一次 2.查看cpu信息 cat /proc/cpuinfo 3.查看内存信息 cat /proc/meminfo 4.清理内存:主 ...
- 关于提交表单时添加自定义值的方式:data中值可绑定function
表单提交时新增自定义值: $.ajaxForm(){ data:{aaa:"12"} } 但是这个是在初始化的时候就绑定进去的,所以值是固定的初始化时候的值,若想添加动态值,可以这 ...