zoukankan      html  css  js  c++  java
  • CLR via C# 读书笔记 运行时序列化

    什么是序列化和反序列化

    序列化(serialization)是将一个对象或者对象图(对象在特定的时间点的一个视图)转换成一个字节流的过程。反序列化(deserialization)是将一个字节流转换回对象图的过程。

    应用场景:

    • 应用程序的状态(对象图)可以保存到磁盘文件或数据库中,并在应用程序下次运行时恢复。
    • 一组对象可以轻松复制到Windows 窗体的剪贴板中,再粘贴回同一个或者另一个应用程序。
    • 将对象按值从一个应用程序域中发送到另一个程序域

    序列化/反序列化快速入门

    引用 System.Runtime.Serialization.Formatters.Binary

    private static MemoryStream SerializeToMemory(object objectGraph) {
        MemoryStream stream = new MemoryStream();
        BinaryFormatter formatter = new BinaryFormatter();
        formatter.Serialize(stream, objectGraph);
        return stream;
    }
    private static Object DeserializeFormMemory(Stream stream) {
        BinaryFormatter formatter = new BinaryFormatter();
        return formatter.Deserialize(stream);
    }
    static void Main(string[] args)
    {
        List<string> objectGraph = new List<string> {"hzd","ian.w","whx1973" };
        Stream stream = SerializeToMemory(objectGraph);
        stream.Position = 0;
        objectGraph = null;
        objectGraph = (List<string>)DeserializeFormMemory(stream);
        foreach (var s in objectGraph)
        {
            Console.WriteLine(s);
        }
    }
    SerializeToMemory方法创建MemoryStream对象,用来做序列化完成后字节存在的容器,创建BinaryFormatter对象formatter(格式化器),调用Serialize方法,传递一个流对象的引用和要被序列化
    的对象的引用。流对象可以是任何一个从System.IO.Stream抽象基类派生的任何类型的一个对象 (MemoryStream,FileStream,NetworkSteam),第二个参数可以是任何东西,如Int32 、String、
    List<String>等等
    DeserializeFormMemory 方法创建 BinaryFormatter 对象 formatter,调用 Deserialize 方法,此方法获取流作为参数,返回对反序列化的对象图中的根对象的一个引用。在内部,格式化器的
    Deserialize方法会检查流的内容,够造流中的所有对象的实例,并初始化所有这些对象的字段,使它们具有与当初序列化时相同的值。通常要将Deserialize方法返回的对象引用转型为应用程序期待的类型。

    使类型可序列化
    类型默认是不可以序列化的,需要定制System.SerializableAttributeattribute(attributeSystem命名空间定义的),SerializableAttribute这个定制attribute只能应用于引用
    类型(class)、值类型(struct)、枚举类型(enum)和委托类型(delegate)。此外SerializableAttribute attribute不会被派生类继承
    控制序列化和反序列化
    SerializableAttribute 这个定制的attribute应用于一个类型时,所有的实例字段(public private protected 等)都会被序列化。使用System.NonSerializedAttribute 定制attribute
    来指明类型的哪些字段不应序列化。此attribute同样位于System命名空间
    [Serializable]
    internal class Circle
    {
        private double m_radius;
        [NonSerialized]
        private Double m_area;
    
        public Circle(double radius)
        {
            m_radius = radius;
            m_area = Math.PI * m_radius * m_radius;
        }
    }
    上述代码中,Circle的对象可以序列化 ,然而反序列化时,Circle对象的 m_area 字段会被设置为 0 ,不能得到正确的结果,修改上面的代码为 
    [Serializable]
    internal class Circle
    {
        private double m_radius;
        [NonSerialized]
        private Double m_area;
    
        public Circle(double radius)
        {
            m_radius = radius;
            m_area = Math.PI * m_radius * m_radius;
        }
        [OnDeserialized]
        private void OnDeserialized(StreamingContext context)
        {
            m_area = Math.PI * m_radius * m_radius;
        }
    }

    在修改的代码中 ,包含了一个用 System.Runtime.Serialization.OnDeserializedAttribute定制的 特性 进行了标记的方法 ,每次反序列化类型的一个实例 ,格式化器都会检查类型中是否定义了一个应用该特性的方法 。除了 OnDeserializedAttribute这个定制的特性 ,System.Runtime.Serialization命名空间还包含 OnDeserializingAttribute,OnSerializingAttribute,OnSerializedAttribute这些定制

    的attribute。



  • 相关阅读:
    Java实现 蓝桥杯VIP 算法训练 字符串逆序
    Java实现 蓝桥杯VIP 算法训练 字符串逆序
    Java实现 蓝桥杯VIP 算法训练 最长字符串
    Java实现 蓝桥杯VIP 算法训练 最长字符串
    Java实现 蓝桥杯VIP 算法训练 最长字符串
    Java实现 蓝桥杯VIP 算法训练 最长字符串
    Java实现 蓝桥杯VIP 算法训练 最长字符串
    Java实现 蓝桥杯VIP 算法训练 成绩的等级输出
    Java实现 蓝桥杯VIP 算法训练 成绩的等级输出
    Qt 自定义model实现文件系统的文件名排序
  • 原文地址:https://www.cnblogs.com/whx1973/p/2631792.html
Copyright © 2011-2022 走看看