C#中List<T>对象的深度拷贝问题

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

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

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

二、List<T>对象中的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(); 
         } 
     //当然前题是List中的对象要实现ICloneable接口
 } 


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

 1 public static T Clone<T>(T RealObject) 
 2 
 3 { 
 4      using (Stream objectStream = new MemoryStream()) 
 5      { 
 6             //利用 System.Runtime.Serialization序列化与反序列化完成引用对象的复制
 7              IFormatter formatter = new BinaryFormatter(); 
 8              formatter.Serialize(objectStream, RealObject); 
 9              objectStream.Seek(0, SeekOrigin.Begin); 
10              return (T)formatter.Deserialize(objectStream); 
11      } 
12 } 

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 
45         public static void Main()
46         {
47             List<tt> lsttt = new List<tt>();
48             tt tt1 = new tt();
49             tt1.Name = "a1";
50             tt1.Sex = "20";
51             lsttt.Add(tt1);
52             List<tt> l333 = new List<tt>();
53             l333.Add(Clone<tt>(lsttt[0]));
54             l333[0].Name = "333333333";
55       }
56   }
57 }
作者:orange1438
出处:http://www.cnblogs.com/orange1438/
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
原文地址:https://www.cnblogs.com/orange1438/p/4544943.html