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);
clone
1. 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小时内删除。