Fork me on GitHub

C#序列化与反序列化以及深拷贝浅拷贝

基于二进制数据流的序列化和反序列化

        /// <summary>
        /// 序列化
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <param name="obj"></param>
        public static void Serialize<T>(T obj)
        {
            try
            {
                using (FileStream fs = new FileStream("Serialize.bin", FileMode.OpenOrCreate))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    bf.Serialize(fs, obj);//序列化
                }
            }
            catch (Exception ex)
            {
                
                throw;
            }
        }
        /// <summary>
        /// 
        /// </summary>
        /// <typeparam name="T"></typeparam>
        /// <returns></returns>
        public static T Deserialize<T>()
        {
            T res = default(T);
            try
            {
                using (FileStream fs=new FileStream("Serialize.bin",FileMode.Open))
                {
                    BinaryFormatter bf = new BinaryFormatter();
                    res = (T)bf.Deserialize(fs);
                }
            }
            catch (Exception)
            {
                
                throw;
            }
            return res;
        }

此时需要序列化的对象必须要声明为可序列化,只需要在声明类的同时采用关键字Serializable,如下:

    [Serializable]
    public class Test 
    {
        public string Name { get; set; }
        public int Age { get; set; }
    }

  以上便可以完成序列化的反序列化的操作。

基于二进制序列化的反序列化的拷贝,C#是基于面型对象的开发语言,自定义声明的类都是采用引用传递的形式,有时候数据的修改对于这种引用传递来说并不是我们想要的结果,因此我们需要该对象的一份拷贝。

以下是基于内存序列化的一种方式:

   public static T Copy<T>(T obj)
        {
            if (obj == null)
            {
                return default(T);
            }
            T res = default(T);
            using (MemoryStream ms = new MemoryStream())
            {
                BinaryFormatter bf = new BinaryFormatter();
                bf.Serialize(ms, obj);//序列化
                ms.Seek(0, SeekOrigin.Begin);
                res = (T)bf.Deserialize(ms);//反序列化
            }
            return res;
        }

这样获取到的拷贝对象跟原来的对象就不是指向同一个地址,这样操作新的对象也不会影响原来的对象。

还有一种是实现ICloneable接口,在Clone方法中返回对象的一个浅拷贝MemberwiseClone。

 public class CopyTest : ICloneable
    {
        public string Name { get; set; }
        public int Age { get; set; }
        public object Clone()
        {
            return this.MemberwiseClone();//获取副本
        }
    }

通过以下方式便可以获得对象的一个拷贝对象:

CopyTest ct = new CopyTest() { Name = "Test", Age = 99 };
CopyTest ct01 = (CopyTest)ct.Clone();

 

posted @ 2019-01-05 00:37  黄高林  阅读(680)  评论(0编辑  收藏  举报