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

摘要:
序列化由特定的格式化程序完成。每个格式化程序提供两种方法:Serialize和Deserialize。格式化程序序列化一个对象后,好的结果被放入流中,因此可以包含任何序列化格式。测试新的NonSerialized时出现问题:“特性”NonSerialized”对于此声明类型无效。它仅对“”字段有效“声明。由于C#3.0的新特性get/set访问器,编译器将在编译时自动为您生成相应的私有变量和变量名。因此,请考虑直接显示声明的私有属性privateintnumber并标记[NonSerialized]属性。

    对象通常都有状态(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”声明有效

基础命名空间:序列化 System.Runtime.Serialization第1张

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

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

运行结果:

基础命名空间:序列化 System.Runtime.Serialization第2张

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类型字段不能被序列化,且元素的属性必须为读/写属性

免责声明:文章转载自《基础命名空间:序列化 System.Runtime.Serialization》仅用于学习参考。如对内容有疑问,请及时联系本站处理。

上篇数据库连接,事务以及Java线程的关系ESP8266恢复出厂设置下篇

宿迁高防,2C2G15M,22元/月;香港BGP,2C5G5M,25元/月 雨云优惠码:MjYwNzM=

相关文章

.NET插件技术-应用程序热升级

今天说一说.NET 中的插件技术,即 应用程序热升级。在很多情况下、我们希望用户对应用程序的升级是无感知的,并且尽可能不打断用户操作的。 虽然在Web 或者 WebAPI上,由于多点的存在可以逐个停用单点进行系统升级,而不影响整个服务。但是 客户端却不能这样做,毕竟用户一直在使用着。 那么有没有一种方式,可以在用户无感知的情况下(即、不停止进程的情况下)对...

MVC3.0视频点播及上传格式转化

在MVC3.0中播放视频文件需要做一下配置:具体配置如下 View Code 1<div class="vidoplay">2<div>3<objectclassid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000"codebase="http://download.macromed...

Xamarin.Forms之Resx

本来使用Resx很简单的事,但是在Xamarin.Studio中遇到问题 [MonoDroid] UNHANDLED EXCEPTION: [MonoDroid] System.Resources.MissingManifestResourceException: Could not find any resources appropriate for t...

C#获取当前路径的方法

C#获取当前路径的方法如下: 1. System.Diagnostics.Process.GetCurrentProcess().MainModule.FileName -获取模块的完整路径。 2. System.Environment.CurrentDirectory -获取和设置当前目录(该进程从中启动的目录)的完全限定目录。 3. System.IO...

使用存储过程(22)

存储过程是数据库开发人员为了使用某一特定的数据库而编写SQL语句集。其他的web应用程序可以调用这些存储过程来访问和操作数据库中的数据,如图: web应用程序可以直接访问数据库,也可以通过存储过程来调用数据库,使用存储过程访问数据库与直接访问数据库,相比有很多优势比如: 假如有一套复杂的SQL语句需要在多个aspx文件中,可以把他们放在一个存储过程,然...

vs.net c# 安装、注册windows service服务,判断服务是否存在,是否启动

vs.net c# 安装、注册windows service服务,判断服务是否存在,是否启动 一、安装服务:private void InstallService(IDictionary stateSaver, string filepath)        {            try            {                Sys...