技术开发 频道

C# Tips:浅拷贝和深拷贝

  序列化/反序列化类实现

  不知道你有没有注意到DataSet对象,对于他提供的两个方法:DataSet.Clone 方法,复制 DataSet 的结构,包括所有 DataTable 架构、关系和约束。不要复制任何数据。

  新 DataSet,其架构与当前 DataSet 的架构相同,但是不包含任何数据。注意 如果已创建这些类的子类,则复本也将属于相同的子类。

  DataSet.Copy 方法复制该 DataSet 的结构和数据.

  新的 DataSet,具有与该 DataSet 相同的结构(表架构、关系和约束)和数据。注意如果已创建这些类的子类,则副本也将属于相同的子类。

  好像既不是浅拷贝,又不是深拷贝,是不是很失望?但是两个结合起来不是我们要的深拷贝吗?看看DataSet的实现,注意序列化接口:ISerializable

  序列化是将对象或对象图形转换为线性字节序列,以存储或传输到另一个位置的过程。反序列化是接受存储的信息并利用它重新创建对象的过程。

  通过 ISerializable 接口,类可以执行其自己的序列化行为。
转换为线性字节序列后并利用其重新创建对象的过程是不是和我们的深拷贝的语意“逐位复制”很相像?

  代码实现如下: 

  [Serializable]
    
public class Person : ICloneable
    {
        
public int Age { get; set; }
        
public string Address { get; set; }
        
public Name Name { get; set; }
        
public object Clone()
        {
            
using (MemoryStream ms = new MemoryStream(1000))
            {
                
object CloneObject;
                BinaryFormatter bf
= new BinaryFormatter(null, new StreamingContext(StreamingContextStates.Clone));
                bf.Serialize(ms,
this);
                ms.Seek(
0, SeekOrigin.Begin);
                
// 反序列化至另一个对象(即创建了一个原对象的深表副本)
                CloneObject = bf.Deserialize(ms);

                
// 关闭流
                ms.Close();
                
return CloneObject;
            }
        }
    }
    [Serializable]
    
public class Name
    {
        
public Name(string frisName, string lastName)
        {
            FristName
= frisName;
            LastName
= lastName;
        }
        
public string FristName { get; set; }
        
public string LastName { get; set; }
    }
}

  注意:通过序列化和反序列化实现深拷贝,其和其字段类型必须标记为可序列化类型,既添加特性(Attribute)[Serializable]。

0
相关文章