【转】C#中List<T>对象的深度拷贝问题
一、List<T>对象中的T是值类型的情况(int 类型等)
对于值类型的List直接用以下方法就可以复制:
1 List<T> oldList = new List<T>();
2 oldList.Add(..);
3 List<T> newList = new List<T>(oldList);
二、List<T>对象中的T是引用类型的情况(例如自定义的实体类)
1、对于引用类型的List无法用以上方法进行复制,只会复制List中对象的引用,可以用以下扩展方法复制:
1 static class Extensions
2 {
3 public static IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
4 {
5 return listToClone.Select(item => (T)item.Clone()).ToList();
6 }
7 //<span style="color:#000000;">当然前题是List中的对象要实现ICloneable接口</span>
8 }
2、另一种用序列化的方式对引用对象完成深拷贝,此种方法最可靠
1 public static T Clone<T>(T RealObject)
2 {
3 using (Stream objectStream = new MemoryStream())
4 {
5 //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
6 IFormatter formatter = new BinaryFormatter();
7 formatter.Serialize(objectStream, RealObject);
8 objectStream.Seek(0, SeekOrigin.Begin);
9 return (T)formatter.Deserialize(objectStream);
10 }
11 }
3、利用System.Xml.Serialization来实现序列化与反序列化
1 public static T Clone<T>(T RealObject)
2 {
3 using(Stream stream=new MemoryStream())
4 {
5 XmlSerializer serializer = new XmlSerializer(typeof(T));
6 serializer.Serialize(stream, RealObject);
7 stream.Seek(0, SeekOrigin.Begin);
8 return (T)serializer.Deserialize(stream);
9 }
10 }
三、对上述几种对象深拷贝进行测试
测试如下:
1 using System;
2 using System.Collections.Generic;
3 using System.Collections ;
4 using System.Linq;
5 using System.Text;
6 using System.IO;
7 using System.Runtime.Serialization;
8 using System.Runtime.Serialization.Formatters.Binary;
9
10 namespace LINQ
11 {
12 [Serializable]
13 public class tt
14 {
15 private string name = "";
16
17 public string Name
18 {
19 get { return name; }
20 set { name = value; }
21 }
22 private string sex = "";
23
24 public string Sex
25 {
26 get { return sex; }
27 set { sex = value; }
28 }
29 }
30
31 class LINQTest
32 {
33 public static T Clone<T>(T RealObject)
34 {
35 using (Stream objectStream = new MemoryStream())
36 {
37 IFormatter formatter = new BinaryFormatter();
38 formatter.Serialize(objectStream, RealObject);
39 objectStream.Seek(0, SeekOrigin.Begin);
40 return (T)formatter.Deserialize(objectStream);
41 }
42 }
43
44 public static void Main()
45 {
46 List<tt> lsttt = new List<tt>();
47 tt tt1 = new tt();
48 tt1.Name = "a1";
49 tt1.Sex = "20";
50 lsttt.Add(tt1);
51 List<tt> l333 = new List<tt>();
52 l333.Add(Clone<tt>(lsttt[0]));
53 l333[0].Name = "333333333";
54 }
55 }
56 }