浅谈C#中List对象的深度拷贝问题
一、List<T>对象中的T是值类型的情况(int类型等)
对于值类型的List直接用以下方法就可以复制:
List<T>oldList=newList<T>(); oldList.Add(..); List<T>newList=newList<T>(oldList);
二、List<T>对象中的T是引用类型的情况(例如自定义的实体类)
1、对于引用类型的List无法用以上方法进行复制,只会复制List中对象的引用,可以用以下扩展方法复制:
staticclassExtensions
{
publicstaticIList<T>Clone<T>(thisIList<T>listToClone)whereT:ICloneable
{
returnlistToClone.Select(item=>(T)item.Clone()).ToList();
}
//当然前题是List中的对象要实现ICloneable接口
}
2、另一种用序列化的方式对引用对象完成深拷贝,此种方法最可靠
publicstaticTClone<T>(TRealObject)
{
using(StreamobjectStream=newMemoryStream())
{
//利用System.Runtime.Serialization序列化与反序列化完成引用对象的复制
IFormatterformatter=newBinaryFormatter();
formatter.Serialize(objectStream,RealObject);
objectStream.Seek(0,SeekOrigin.Begin);
return(T)formatter.Deserialize(objectStream);
}
}
3、利用System.Xml.Serialization来实现序列化与反序列化
publicstaticTClone<T>(TRealObject)
{
using(Streamstream=newMemoryStream())
{
XmlSerializerserializer=newXmlSerializer(typeof(T));
serializer.Serialize(stream,RealObject);
stream.Seek(0,SeekOrigin.Begin);
return(T)serializer.Deserialize(stream);
}
}
三、对上述几种对象深拷贝进行测试
测试如下:
usingSystem;
usingSystem.Collections.Generic;
usingSystem.Collections;
usingSystem.Linq;
usingSystem.Text;
usingSystem.IO;
usingSystem.Runtime.Serialization;
usingSystem.Runtime.Serialization.Formatters.Binary;
namespaceLINQ
{
[Serializable]
publicclasstt
{
privatestringname="";
publicstringName
{
get{returnname;}
set{name=value;}
}
privatestringsex="";
publicstringSex
{
get{returnsex;}
set{sex=value;}
}
}
classLINQTest
{
publicstaticTClone<T>(TRealObject)
{
using(StreamobjectStream=newMemoryStream())
{
IFormatterformatter=newBinaryFormatter();
formatter.Serialize(objectStream,RealObject);
objectStream.Seek(0,SeekOrigin.Begin);
return(T)formatter.Deserialize(objectStream);
}
}
publicstaticvoidMain()
{
List<tt>lsttt=newList<tt>();
tttt1=newtt();
tt1.Name="a1";
tt1.Sex="20";
lsttt.Add(tt1);
List<tt>l333=newList<tt>();
l333.Add(Clone<tt>(lsttt[0]));
l333[0].Name="333333333";
}
}
}
以上这篇浅谈C#中List