C#中ListT 对象的深度拷贝问题(Clone )
⼀、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. List<T> oldList =new List<T>();
2. oldList.Add(..);
3. List<T> newList =new List<T>(oldList);
clone1. staticclass Extensions
2. {
3. publicstatic IList<T> Clone<T>(this IList<T> listToClone) where T: ICloneable
4. {
5. return listToClone.Select(item => (T)item.Clone()).ToList();
6. }
7. //<span >当然前题是List 中的对象要实现ICloneable 接⼝</span> 8. }
public static T Clone<T>(T RealObject)
{ using (Stream objectStream = new MemoryStream()) { //利⽤ System.Runtime.Serializ
ation 序列化与反序列化完成引⽤对象的复制 IFormatter formatter = new BinaryFormatter(); formatter.Serialize(objectStream, RealObject); objectStream.Seek(0, SeekOrigin.Begin); return (T)formatter.Deserialize(objectStream); } }
3、利⽤System.Xml.Serialization 来实现序列化与反序列化
1. publicstatic 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. }
1. publicstatic 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. }
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);
}
}
三、对上述⼏种对象深拷贝进⾏测试
1. 测试如下:
2. using System;
3. using System.Collections.Generic;
4. using System.Collections ;
5. using System.Linq;
6. using System.Text;
7. using System.IO;
8. using System.Runtime.Serialization;
9. using System.Runtime.Serialization.Formatters.Binary;
10.
11. namespace LINQ
12. {
13. [Serializable]
14. public class tt
15. {
16. private string name = "";
17.
18. public string Name
19. {
20. get {return name; }
21. set { name = value; }
22. }
23. privatestring sex ="";
24.
25. publicstring Sex
26. {
27. get {return sex; }
28. set { sex = value; }
29. }
30. }
31.
32. class LINQTest
33. {
34. public static T Clone<T>(T RealObject)
35. {
36. using (Stream objectStream =new MemoryStream())
37. {
38. IFormatter formatter =new BinaryFormatter();
39. formatter.Serialize(objectStream, RealObject);
40. objectStream.Seek(0, SeekOrigin.Begin);
41. return (T)formatter.Deserialize(objectStream);
42. }
43. }
44.
45.
46. public static void Main()
47. {
48. List<tt> lsttt =new List<tt>();
49. tt tt1 =new tt();
50. tt1.Name ="a1";
51. tt1.Sex ="20";
52. lsttt.Add(tt1);
53. List<tt> str=new List<tt>();
54. str.Add(Clone<tt>(lsttt[0]));
55. str[0].Name ="lv";
56. }
57. }
58. }
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论