一、List对象中的T是值类型的情况(int 类型等)

对于值类型的List直接用以下方法就可以复制:

List<T> oldList = new List<T>();
oldList.Add(..);
List<T> newList = new List<T>(oldList);

二、List对象中的T是引用类型的情况(例如自定义的实体类)

1、对于引用类型的List无法用以上方法进行复制,只会复制List中对象的引用,可以用以下扩展方法复制:

static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
//<span style="color:#000000;">当然前题是List中的对象要实现ICloneable接口</span>
}

2、另一种用序列化的方式对引用对象完成深拷贝,此种方法最可靠

public static T Clone<T>(T RealObject)
{
using (Stream objectStream = new MemoryStream())
{
//利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}

3、利用System.Xml.Serialization来实现序列化与反序列化

public static T Clone<T>(T RealObject)
{
using(Stream stream=new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, RealObject);
stream.Seek(, SeekOrigin.Begin);
return (T)serializer.Deserialize(stream);
}
}

三、对上述几种对象深拷贝进行测试

using System;
using System.Collections.Generic;
using System.Collections ;
using System.Linq;
using System.Text;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary; namespace LINQ
{
[Serializable]
public class tt
{
private string name = ""; public string Name
{
get { return name; }
set { name = value; }
}
private string sex = ""; public string Sex
{
get { return sex; }
set { sex = value; }
}
} class LINQTest
{
public static T Clone<T>(T RealObject)
{
using (Stream objectStream = new MemoryStream())
{
IFormatter formatter = new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
} public static void Main()
{
List<tt> lsttt = new List<tt>();
tt tt1 = new tt();
tt1.Name = "a1";
tt1.Sex = "";
lsttt.Add(tt1);
List<tt> l333 = new List<tt>();
l333.Add(Clone<tt>(lsttt[]));
l333[].Name = "";
}
}
}

四、其他方式

T如果是引用类型的,采用如下方式初始化列表:

ObservableCollection<T> tempList = new ObservableCollection<T>(sourceList);
sourceList.Clear(); // 清除源数据列表
System.Console.WriteLine(tempList.Count); // 副本数据并未改变

【C#】List<T>对象的深复制的更多相关文章

  1. Java中对象的深复制和浅复制详解

    1.浅复制与深复制概念 ⑴浅复制(浅克隆) 被复制对象的所有变量都含有与原来的对象相同的值,而所有的对其他对象的引用仍然指向原来的对象.换言之,浅复制仅仅复制所考虑的对象,而不复制它所引用的对象. ⑵ ...

  2. Objective-C:OC内部可变对象和不可变对象的深(复制)拷贝问题思考:

    OC内部:可变对象和不可变对象的深(复制)拷贝问题思考:   不可变对象:  例如NSString对象,因为NSString对象是常量字符串,所以,不可以更改其内容,但是可以修改指向该字符串的指针指向 ...

  3. java对象实现深复制的方法

    p2 = (Person)org.apache.commons.lang3.ObjectUtils.cloneBean(p); Person p2 = new Person(); p2 = (Pers ...

  4. JavaScript 对象的深复制

    对象的深复制 源对象的属性更改,不会引起复制后的对象个属性的更改 源对象的任何属性与子属性与新对象的之间没有任何引用关系 Coding: /* 对象的深复制: 1 初始化目标对象 如果没有指定目标对象 ...

  5. js 复制对象的深复制与浅复制

    1.潜复制(修改新对象会改变原对象) var baz = {a:'hello', b: {c:'my', d:'friend'}} var foo = baz foo.a="better&q ...

  6. C# 对象的深复制和浅复制

    2019年第一篇博客,好吧,又大了一岁了,继续加油吧. 正文: C# 中的对象,众所周知是引用类型,那么如何复制对象Object呢,我们来看看下面这段代码: public class User { p ...

  7. js 对象的深复制 解决不能复制undefined (递归)

    用普通的拷贝  JSON.parse和 JSON.stringify 进行对象拷贝是不会拷贝undefined //普通的拷贝   const obj = {         a: {         ...

  8. java hasmap对象的深复制实现:字节码复制和对象序列化成字符串复制比较。

    /** * Created by Administrator on 2016/11/23. */ public class test { public static void main(String[ ...

  9. js对象克隆, 深复制.

    亲测有效: //对象克隆 function clone(obj) { // Handle the 3 simple types, and null or undefined if (null == o ...

随机推荐

  1. Centos下cacti的安装

    介绍 Cacti是一套基于PHP,MySQL,SNMP及RRDTool开发的网络流量监测图形分析工具.Cacti是通过 snmpget来获取数据,使用 RRDtool绘画图形.它提供了非常强大的数据和 ...

  2. MySQL C 客户端的内存泄漏问题

    我们的一个服务器软件在线上环境运行时出现了内存缓慢增长的问题. 用valgrind测试 MySQL的C客户端mysqlclient发现,它在正常的使用中会被valgrind报出存在内存泄漏. 1 正常 ...

  3. Android学习系列(6)--App模块化及工程扩展

    这篇文章是Android开发人员的必备知识,是我特别为大家整理和总结的,不求完美,但是有用. 1.需求    无论是在.net还是java平台,合理的分层架构是最普遍的模块化思路之一.    dll, ...

  4. iOS设备的标识---UUID和IDFA

    一:1.1 :UDID 简介:UDID的全称是Unique Device Identifier,顾名思义,它就是苹果IOS设备的唯一识别码,它由40个字符的字母和数字组成.在很多需要限制一台设备一个账 ...

  5. Sourcetree 更新git账号密码

    删除Sourcetree 缓存文件(只需要删密码文件),文件位置: Mac: ~/Library/Application Support/SourceTree Windows: C:\Users\US ...

  6. 关于Andorid的RecyclerView在V7包下找不到的解决办法

      关于Andorid的RecyclerView在V7包下找不到的解决办法 最近在学习使用RecyclerView替换现有的ListView,看了几篇文章.当准备自己动手实现的时候发现,V7包下找不到 ...

  7. 【JEECG_3.7.1】列表多表头的设计

    先看下多表头的设计: 在这个多表头的表单当中,我们可以按照从上到下和从左往右的划分方式,将表头划分成三行十列,分别是: 列表标签 人员信息.部门信息.工资.入职状态.创建日期.操作 名称.年龄.性别. ...

  8. spring cloud中通过配置文件自定义Ribbon负载均衡策略

    一.Ribbon中的负载均衡策略 1.Ribbon中支持的负载均衡策略 AvailabilityFilteringRule:过滤掉那些因为一直连接失败的被标记为circuit tripped的后端se ...

  9. 如何把scratch转成一个swf文件或者exe执行文件

    scratch作为一款启蒙用的积木式编程软件,非常受人欢迎,但是,现在有一个问题就是,无法将之转变成一个可执行文件,以便和周边的人们分享. 我个人认为把scratch转变为一个可执行的exe文件,并不 ...

  10. [svc]linux日志和安全日志

    last详解: http://www.cnblogs.com/kerrycode/p/4223751.html