zoukankan      html  css  js  c++  java
  • 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();
  • 相关阅读:
    tomcat请求流程浅解
    jdk8为啥lambda表达式建议你用冒号形式调用方法
    打印目录树形结构
    类斐波那契数列的java实现
    sping boot 如何将外部引入的jar包打到fat jar里面
    java多线程之生产者消费者
    Hadoop、Hbase、ZooKeeper的搭建
    java 静态代码块、构造代码块、构造函数调用顺序
    MyBatis的 or 和and 问题
    mysql
  • 原文地址:https://www.cnblogs.com/hglSV/p/10223171.html
Copyright © 2011-2022 走看看