zoukankan      html  css  js  c++  java
  • 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/
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    solr 的全量更新与增量更新
    solr 服务器的搭建
    Mysql 问题
    App 微信支付
    App 支付宝支付
    Linux 常见命令
    [备注] 钉钉使用教程
    PARAMETER和ARGUMENT的区别
    无界面浏览器
    URLs ...
  • 原文地址:https://www.cnblogs.com/orange1438/p/4544943.html
Copyright © 2011-2022 走看看