1. 程式人生 > 其它 >C#深拷貝方法

C#深拷貝方法

  • 概述

  為什麼要用到深拷貝呢?比如我們建了某個類Person,並且例項化出一個物件,然後,突然需要把這個物件複製一遍,並且複製出來的物件要跟之前的一模一樣,來看下我們一般會怎麼做。

  • 方法一(利用反射實現)
    public static T DeepCopy<T>(T obj)
    {
      //如果是字串或值型別則直接返回
      if (obj is string || obj.GetType().IsValueType) return obj;
    
      object retval = Activator.CreateInstance(obj.GetType());
      FieldInfo[] fields = obj.GetType().GetFields(BindingFlags.Public | BindingFlags.NonPublic | BindingFlags.Instance | BindingFlags.Static);
      foreach (FieldInfo field in fields)
      {
        try { field.SetValue(retval, DeepCopy(field.GetValue(obj))); }
        catch { }
      }
      return (T)retval;
    }
    
  • 方法二(利用XML序列化和反序列化實現)

    public T DeepCopy<T>(T obj)
    {
          object retval;
          using (MemoryStream ms = new MemoryStream())
          {
            XmlSerializer xml = new XmlSerializer(typeof(T));
            xml.Serialize(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);
            retval = xml.Deserialize(ms);
            ms.Close();
          }
          return (T)retval;
    }
    
  • 方法三(利用二進位制序列化和反序列實現)

    public static T DeepCopy<T>(T obj)
    {
      object retval;
      using (MemoryStream ms = new MemoryStream())
      {
        BinaryFormatter bf = new BinaryFormatter();
        //序列化成流
        bf.Serialize(ms, obj);
        ms.Seek(0, SeekOrigin.Begin);
        //反序列化成物件
        retval = bf.Deserialize(ms);
        ms.Close();
      }
      return (T)retval;
    } 
  • 方法四(DataContractSerializer實現)
    //利用silverlight DataContractSerializer實現,用於在silverlight 客戶端使用
    public static T DeepCopy<T>(T obj)
    {
          object retval;
          using (MemoryStream ms = new MemoryStream())
          {
            DataContractSerializer ser = new DataContractSerializer(typeof(T));
            ser.WriteObject(ms, obj);
            ms.Seek(0, SeekOrigin.Begin);
            retval = ser.ReadObject(ms);
            ms.Close();
          }
          return (T)retval;
    }