首页 > 其他分享 >8.10 序列化(第二版)

8.10 序列化(第二版)

时间:2025-01-13 23:22:15浏览次数:1  
标签:XML string 第二 8.10 fullName 序列化 public CONSIDER

8.10 序列化(第二版)

  • .NET框架提供了三种主要的序列化技术,如下:

    • 数据协定(Data Contract) 序列化;
    • XML 序列化;
    • 运行时 序列化(二进制和SOAP)

image

  • DO​:在设计新的类型时考虑到序列化。

    如果类型实例需要持久化,或需要传输,则设计时要考虑如何序列化。

1 选择要支持的序列化技术

  • DO​:优先支持 数据协定 序列化。

  • CONSIDER​:如果需要 控制序列化方式 ,可以只支持XML序列化,或同时支持数据协定序列化和XML序列化。

  • CONSIDER​:如果需要跨.NET Remoting的边界传输类型,应实现 运行时序列化

2 对数据协定序列化的支持

  • CONSIDER​:如果类型会被用于部分可信(partial trust)环境,序列化成员要定义为 公有

    • 完全可信(full trust)环境下,Data Contract可以对所有成员进行序列化;部分可信环境下,仅对公有成员进行序列化。

  • DO ​:需要序列化的属性 必须有 getter和setter。

    • 如果仅用于完全可信的环境中,getter和setter可以是非公有的。

  • DO​:使用序列化回调函数在反序列化时初始化实例。
    序列化回调函数通过Attribute标注,包括:

    • OnDeserializedAttribute​​ 反序列化后 触发
    • OnDeserializingAttribute​​ 反序列化前 触发
    • OnSerializingAttribute​​ 序列化前 触发
    • OnSerializedAttribute​​ 序列化后 触发

    我们可以在这些回调函数中进行一些附加操作

    • [DataContract]
      class Person {
          [DataMember] string lastName;
          [DataMember] string firstName;
          string fullName;
        
          public Person(string firstName, string lastName) {
              this.lastName = lastName;
              this.firstName = firstName;
              fullName = firstName + " " + lastName;
          }
        
          public string FullName => fullName;
        
          [OnDeserialized]
          void OnDeserialized(StreamingContext context) {
              fullName = firstName + " " + lastName;
          }
      }
      

  • CONSIDER​:使用 KnowTypeAttribute ​标注反序列化时会遇到的具体来类型。

    KnowTypeAttribute​ 有两个构造函数,KnownTypeAttribute(Type type)​ 传入类型,KnownTypeAttribute(string methodName)​ 传入返回Type[]​ 的静态方法:

    [KnownType("GetKnownTypes")]
    [DataContract]
    public class Person {
        ...
        public static Type[] GetKnownTypes() {
            return new[] { typeof(DateTime, School, ... ) };
        }
    }
    

  • DO​:创建、改变序列化类型时要考虑向后、向前兼容性。

    Data Contract反序列化与以下因素相关:

    • 数据成员的名字
    • 类型
    • 顺序

    改变这些内容会导致反序列化失败。如果要修改,应进行特殊处理(可以通过DataMember的可选参数进行标注)。

  • CONSIDER​:可以通过实现 IExtensibleDataObject 支持新老版本的双向转换。

    [DataContract]
    class Person : IExtensibleDataObject {
        ...
        ExtensionDataObject serializationData;
        ExtensionDataObject IExtensibleDataObject.ExtensionData {
            get => serializationData;
            set => serializationData = value;
        }
    }
    

3 对XML序列化的支持

DataContract 是.NET框架中主要(默认)序列化技术,但也存在一些不支持的场景(如多维数组)。此时可以使用XML序列化,我们可以通过它完全控制序列化过程。

  • AVOID​:除非有强烈的理由控制输出的内容,否则不要使用 XML序列化

    我们可以通过特性对生成的XML加以控制:

    public class Address {
        [XmlAttribute]  // 序列化时作为XML属性,而非元素
        public string Name { get { return "John Smith";} set { } }
      
        [XmlElement(ElementName = "StreetLine")]  // 指明元素名称
        public string Street = "1 Some Street";
    }
    

  • CONSIDER​:应用XML序列化Attribute后,如果生成的XML内容仍不满足要求,可以实现 IXmlSerializable 接口。

    该接口有两个方法,ReadXml​和WriteXml​,可以用它们完全控制生成的XML内容。如果上述接口还不够,可以给类型添加XmlSchemaProviderAttribute​,用于对XML架构(XML schema)进行控制。

4 对运行时序列化的支持

  • CONSIDER​:如果类型会被用于.NET Remoting,考虑支持 运行时序列化

    例如:System.AddIn用到了.NET Remoting,因此System.AddIn的外接程序之间传输的所有类型都必须支持运行时序列化。

    [Serializable]  // 通过添加该特性便可支持运行时序列化。
    public class Person {
        ...
    }
    

  • CONSIDER​:如果想要完全控制序列化的整个过程,实现 ISerializable 接口。

    该接口包含一个ISerializable.GetObjectData​方法,用于序列化,我们还需定义一个构造函数,用于反序列化。该构造函数应定义为protected,如果是密封类型,则是private。
    接口方法要显式实现,并标注SecurityAction.LinkDemand​,保证只有完全可信的代码和运行时序列化程序才能访问该成员;构造函数要定义为protected,有两个参数。
    具体实现参见示例代码。

    [Serializable]
    public class Person : ISerializable {
        string fullName;
      
        public string FullName {
            get => fullName;
            set => fullName = value;
        }
      
        public Person() { }
        // 反序列化构造函数
        protected Person(SerializationInfo info, StreamingContext context) {
            if (info == null)
                throw new System.ArgumentNullException("info");
            fullName = (string)info.GetValue("name", typeof(string));
        }
      
        // 接口引入的序列化方法。
        [SecurityPermission(SecurityAction.LinkDemand, 
           Flags = SecurityPermissionFlag.SerializationFormatter)]
        void ISerializable.GetObjectData(SerializationInfo info, StreamingContext context) {
            if (info == null)
                throw new System.ArgumentNullException("info");
            info.AddValue("name", fullName);
        }
    }
    

标签:XML,string,第二,8.10,fullName,序列化,public,CONSIDER
From: https://www.cnblogs.com/hihaojie/p/18669609/810-serialization-second-edition-zoesle

相关文章

  • java第二章数组学习
    java第二章数组数组的概念和特点数组(Array),是多个相同类型数据按一定顺序排列的集合,并使用一个名字命名,并通过编号的方式对这些数据进行统一管理。特点数组本身是引用数据类型,而数组中的元素可以是任何数据类型,包括基本数据类型和引用数据类型。创建数组对象会在内存中开......
  • go序列化库--msgpack
    简介msgpack是一个基于二进制高效的对象序列化类库,可用于跨语言通信。它可以像JSON那样,在许多种语言之间交换结构对象。但是它比JSON更快速也更轻巧。支持Python、Ruby、Java、C/C++、Go等众多语言。宣称比GoogleProtocolBuffers还要快4倍。官方的说法它像JSON,但更......
  • 方法引用与lambda底层原理&Java方法引用、lambda能被序列化么?
    0.引入最近笔者使用flink实现一些实时数据清洗(从kafka清洗数据写入到clickhouse)的功能,在编写flink作业后进行上传,发现运行的时候抛出:java.io.NotSerializableException,错误消息可能类似于“org.apache.flink.streaming.api.functions.MapFunctionimplementationisnotser......
  • 方法引用与lambda底层原理&Java方法引用、lambda能被序列化么?
    系列文章目录和关于我0.引入最近笔者使用flink实现一些实时数据清洗(从kafka清洗数据写入到clickhouse)的功能,在编写flink作业后进行上传,发现运行的时候抛出:java.io.NotSerializableException,错误消息可能类似于“org.apache.flink.streaming.api.functions.MapFunctionimplemen......
  • 【Weblogic T3协议】反序列化漏洞分析(上)
    免责声明此文章中所涉及的技术、思路和工具仅供网络安全学习为目的,不得以盈利为目的或非法利用,否则后果自行承担!一、前言在初入安全的时候,就听说过weblogic的大名,当然听说的并不是weblogic如何如何好用,而是因为其漏洞出现频率实在是有点高...于是乎,便抱着学习的心态跟了跟web......
  • 统计学习方法(第二版) 第七章 支持向量机(第一节)
    本章主要介绍线性可分支持向量机与硬间隔最大化。前提知识:统计学习方法(第二版)第七章拉格朗日对偶性-CSDN博客目录前言问题引出与思考回顾1.回顾感知机2.回顾逻辑回归3.寻找更好的超平面一、线性可分支持向量机与硬间隔最大化1.线性可分支持向量机2.函数间隔与几......
  • 第二章:HTML的常用标签
    目录一、标签二、常用标签1.排版标签2.文本标签3.图片标签img4.列表5.表格6.表单7.框架标签iframe三、总结一、标签HTML是一种标记性语言,主要通过各种标签来呈现页面,不同标签有不同的语义和效果。注意:效果并不重要,标签最重要的是语义,所有的效果都可以通过css进行......
  • 统计学习方法(第二版) 第七章 拉格朗日对偶性
            在约束最优化问题中,常常利用拉格朗日对偶性(Lagrangeduality)将原始问题转换为对偶问题,通过解对偶问题而得到原始问题的解。该方法应用在许多统计学习方法中,例如,最大熵模型与支持向量机。这里简要叙述拉格朗日对偶性的主要概念和结果。    这里就......
  • 代码随想录算法训练营第二天 | Leetcode 209、Leetcode 59、kama 44、kama 58
    Leetcode209#include"iostream"#include"vector"usingnamespacestd;intminSubArrayLen(inttarget,vector<int>&nums){intlen=INT32_MAX;intsum=0;for(intj=0,i=0;j<nums.size();j++){......
  • 反序列化链分析
    反序列化链1分析过程Thinkphp8反序列化调用链从ResourceRegister#__destruct()开始,最终调用到Validate#is()下,该方法下存在一个call_user_func_array()可供我们调用执行命令反序列化链的起点在ResourceRegister#__destruct()下,其中......