• 【C#】List<T>对象的深复制


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

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

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

    二、List对象中的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();   
        }   
        //<span style="color:#000000;">当然前题是List中的对象要实现ICloneable接口</span>  
    }   

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

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

    3、利用System.Xml.Serialization来实现序列化与反序列化

    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);  
        }  
    }

    三、对上述几种对象深拷贝进行测试

    using System;  
    using System.Collections.Generic;  
    using System.Collections ;  
    using System.Linq;  
    using System.Text;  
    using System.IO;  
    using System.Runtime.Serialization;  
    using System.Runtime.Serialization.Formatters.Binary;  
    
    namespace LINQ  
    {  
        [Serializable]  
        public class tt  
        {  
            private string name = "";  
    
            public string Name  
            {  
                get { return name; }  
                set { name = value; }  
            }  
            private string sex = "";  
    
            public string Sex  
            {  
                get { return sex; }  
                set { sex = value; }  
            }  
        }  
    
        class LINQTest  
        {  
            public static T Clone<T>(T RealObject)   
            {   
                using (Stream objectStream = new MemoryStream())   
                {   
                    IFormatter formatter = new BinaryFormatter();   
                    formatter.Serialize(objectStream, RealObject);   
                    objectStream.Seek(0, SeekOrigin.Begin);   
                    return (T)formatter.Deserialize(objectStream);   
                }   
            }  
    
    
            public static void Main()  
            {  
                List<tt> lsttt = new List<tt>();  
                tt tt1 = new tt();  
                tt1.Name = "a1";  
                tt1.Sex = "20";  
                lsttt.Add(tt1);  
                List<tt> l333 = new List<tt>();  
                l333.Add(Clone<tt>(lsttt[0]));  
                l333[0].Name = "333333333";  
          }  
       }  
    }

    四、其他方式

    T如果是引用类型的,采用如下方式初始化列表:

    ObservableCollection<T> tempList = new ObservableCollection<T>(sourceList);
    sourceList.Clear(); // 清除源数据列表
    System.Console.WriteLine(tempList.Count); // 副本数据并未改变
  • 相关阅读:
    Jenkins自动化部署入门详细教程
    单元测试
    弱网测试
    Token、Cookie和Session
    测试开发人员必备Linux命令
    TestNG(一)
    char和varchar
    你平时会看日志吗,一般会出现哪些异常(Exception)
    内存溢出和内存泄漏的区别,产生原因以及解决方案
    测试一个电梯
  • 原文地址:https://www.cnblogs.com/guxin/p/csharp-list-collection-deep-copy.html
Copyright © 2020-2023  润新知