• 基础命名空间:序列化 System.Runtime.Serialization


        对象通常都有状态(state),从一个对象中抽取这种状态,不论是将它存储于某地,还是通过网络传送,这种抽取动作称为“将一个对象序列化”,而反向处理过程,从一个被序列化的状态重建一个对象即为反序列化。

        序列化工作系由一个特定的格式化器(formatter)完成,每个格式化器都提供Serialize和Deserialize两个方法。当格式化器将某个对象序列化后,所得好结果被放入一个流(Stream)中,(所谓的流是字节序列的一个抽象概念)因此可以包容任何序列化格式。一对象被存储于一个流之中,对象的状态好久可以被存储于磁盘上(或者说被持久化(persistent))

        对于一个可被序列化的类型,只需要给他表上[Serializable]特性,也可以只赋给某个特定的字段

       NonSerialized 指明被标记的字段不可序列化

    下面是自己练习的示例:

    1.二进制序列化

    using System;
    using System.Collections.Generic;
    using System.IO;
    using System.Linq;
    using System.Runtime.Serialization;
    using System.Runtime.Serialization.Formatters.Binary;
    using System.Text;
    using System.Threading.Tasks;
    
    namespace SerializableTest
    {
        public class Program
        {
            static void Main(string[] args)
            {
                Goods good = new Goods();
                good.name = "苹果";
                good.price = 10;
                good.type = "水果";
    
                string dir = System.AppDomain.CurrentDomain.BaseDirectory;
                
                //序列化
                IFormatter formatter = new BinaryFormatter();
                Stream stream = new FileStream(dir+"test.bin", FileMode.Create, FileAccess.Write);
                formatter.Serialize(stream, good);
                stream.Close();//必须关闭
                
                //反序列化
                IFormatter reformatter = new BinaryFormatter();
                Stream filestream = new FileStream(dir+"test.bin", FileMode.Open, FileAccess.Read);
    
                //返回Object类型,必须强制转换
                Goods newgood = (Goods)reformatter.Deserialize(filestream);
    
                Console.WriteLine(newgood.name);
                Console.WriteLine(newgood.price);
                Console.WriteLine(newgood.type);
                Console.ReadLine();
    
            }
        }
    
        [Serializable]
        public class Goods
        {
            /// <summary>
            /// 名称
            /// </summary>
            public string name { get; set; }
    
            /// <summary>
            /// 价格
            /// </summary>
            public double price { get; set; }
    
            /// <summary>
            /// 分类
            /// </summary>
            public string type { get; set; }
        }
    }

       上例使用二进制格式化器BinaryFormatter:System.Runtime.Serialization.Formatters.Binary;

    注:Iformatter接口序列化对象时,只需要提供了Stream流对象就行了。将对象序列化到文件流(FileStream)、内存流(MemoryStream)、网络流(NetworkStream)都可以。

    在测试 特新NonSerialized 时出现了点问题:“特性“NonSerialized”对此声明类型无效。它只对“field”声明有效

          由于C#3.0 的新特性get/set访问器,在编译的时候,编译器会自动为你生成对应的私有变量,变量名自动生成。

    因此考虑 直接显示声明私有属性 private int number,并标注[NonSerialized]特性。

    运行结果:

    2.XML序列化

       XML序列化,对象被以XML格式保存,XML序列化常常用在Web服务项目里(最近的项目里看到有模块用到,所以自己学习一下)

          System.Xml.Serialization命名空间:含有使用XML序列化所需要的类和功能

                 XmlSerializer类,提供序列化Serialeze()和反序列话Deserialize()方法。

                 XmlIgnore属性,让XmlSerializer类跳过不序列化的成员(XML序列化 Serializable和NoSerialized属性将被忽略,而是使用XmlIgnore属性,它的作用与NoSerialized类似)

                例如:

    /// <summary>
    /// 分类
    /// </summary>
    [XmlIgnore]
    public string type { get; set; }

     Goods good = new Goods();
                good.name = "苹果";
                good.price = 10;
                good.type = "水果";
                good.Number = 12;
    
                string dir = System.AppDomain.CurrentDomain.BaseDirectory;
    
                //序列化
                XmlSerializer formatter = new XmlSerializer(typeof(Goods));
                FileStream stream = new FileStream(dir + "test.bin", FileMode.Create, FileAccess.Write);
                formatter.Serialize(stream, good);
                stream.Close();//必须关闭
    
                //反序列化
                XmlSerializer reformatter = new XmlSerializer(typeof(Goods));
                FileStream filestream = new FileStream(dir + "test.bin", FileMode.Open, FileAccess.Read);
    
                //返回Object类型,必须强制转换
                Goods newgood = (Goods)reformatter.Deserialize(filestream);
    
                Console.WriteLine("名称:" + newgood.name);
                Console.WriteLine("价格:" + newgood.price);
                Console.WriteLine("种类:" + newgood.type);
                Console.WriteLine("数量:" + newgood.Number);
                Console.ReadLine();

    持久化后的XML数据

    <?xml version="1.0"?>
    <Goods xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
      <name>苹果</name>
      <price>10</price>
      <Number>12</Number>
    </Goods>

    可以发现加了[XmlIgnore]特性的type字段没有被序列化

    注:public int Number被序列化了,private int number 没有被序列化,据说XML序列化 private类型字段不能被序列化,且元素的属性必须为读/写属性

  • 相关阅读:
    构造函数语义学之Default Constructor构建操作
    c++子类继承父类的覆盖问题
    C++中自己理解的一些细节哈
    学习C++所需看的书和顺序
    C++中强制变换之const_cast
    jquery锚点跳转
    关于iPhone X 适配
    input图片上传并显示查看判断图片类型
    jquery操作按钮修改对应input属性
    织梦dedecms会员中心分类管理无法修改、删除分类名
  • 原文地址:https://www.cnblogs.com/ashleyboy/p/3667715.html
Copyright © 2020-2023  润新知