C#中List<T>对象的深度拷贝问题 (Clone)
2013-04-28 09:59
459 查看
一、List<T>对象中的T是值类型的情况(int 类型等)
对于值类型的List直接用以下方法就可以复制:
List<T> oldList =new List<T>();
oldList.Add(..);
List<T> newList =new List<T>(oldList);
List<T> oldList = new List<T>();
oldList.Add(..);
List<T> newList = new List<T>(oldList);
二、List<T>对象中的T是引用类型的情况(例如自定义的实体类)
1、对于引用类型的List无法用以上方法进行复制,只会复制List中对象的引用,可以用以下扩展方法复制:
staticclass Extensions
{
publicstatic IList<T> Clone<T>(this IList<T> listToClone)
where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
//<span style="color: rgb(0, 0, 0);">当然前题是List中的对象要实现ICloneable接口</span>
}
static class Extensions
{
public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
{
return listToClone.Select(item => (T)item.Clone()).ToList();
}
//当然前题是List中的对象要实现ICloneable接口
}
2、另一种用序列化的方式对引用对象完成深拷贝,此种方法最可靠
publicstatic T Clone<T>(T RealObject)
{
using (Stream objectStream = new MemoryStream())
{
//利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
IFormatter formatter =new BinaryFormatter();
formatter.Serialize(objectStream, RealObject);
objectStream.Seek(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}
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(0, SeekOrigin.Begin);
return (T)formatter.Deserialize(objectStream);
}
}
3、利用System.Xml.Serialization来实现序列化与反序列化
publicstatic T Clone<T>(T RealObject)
{
using(Stream stream=new MemoryStream())
{
XmlSerializer serializer =new XmlSerializer(typeof(T));
serializer.Serialize(stream, RealObject);
stream.Seek(0, SeekOrigin.Begin);
return (T)serializer.Deserialize(stream);
}
}
public static T Clone<T>(T RealObject)
{
using(Stream stream=new MemoryStream())
{
XmlSerializer serializer = new XmlSerializer(typeof(T));
serializer.Serialize(stream, RealObject);
stream.Seek(0, 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; }
}
privatestring sex ="";
publicstring 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(0, 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 ="20";
lsttt.Add(tt1);
List<tt> str=new List<tt>();
str.Add(Clone<tt>(lsttt[0]));
str[0].Name ="lv";
}
}
}
相关文章推荐
- C#中List<T>对象的深度拷贝问题
- C#中List<T>对象的深度拷贝问题
- C#中List<T>对象的深度拷贝问题
- C#中List<T>对象的深度拷贝问题
- List<Object>装的是对象 排序问题
- js给<object>视频赋值 延迟加载,解决不能修改的html对象的问题 .
- 算法积累 <1>整数划分问题
- startActivityforResult传递List<Object>参数错误问题
- HUDSON邮件模板问题 <众里寻他千百度,蓦然回首,那‘人’却在灯火阑珊处>
- List<>引起的nullpointerexception问题
- 面向对象基础<一>
- 关于八数码问题中的状态判重的三种解决方法(编码、hash、<set>)
- 解决<s:file>上传文件大小和 不能获取文件问题
- Map对象与JavaBean互转,List<Map>与List<JavaBean>互转等
- <转>防止刷新/后退引起的重复提交问题的Java Token代码,非Struts
- 针对表单的get提交与超链接中<a></a>乱码问题
- jsp中<basePath>问题
- C++中输入输出<< 和>>重载,以便适应输出输入一个对象
- 关于‹和›转义成< 和>的问题
- <转> 面试java高级工程师、项目经理等的常见问题