重庆熊猫 Loading

.NET中的序列化和反序列化详解

更新记录
本文迁移自Panda666原博客,原发布时间:2021年7月1日。

一、.NET中的序列化介绍

1.1序列化基础

序列化(Serialization),也叫串行化。通过将对象转换为字节流,从而存储对象到内存,数据库或文件的过程。主要用途是保存对象的状态数据,以便进行传输和需要时重建对象。对象的状态主要包括字段和属性(不包含方法和事件)。
image
反序列化(Deserialization):将序列化后的数据重新解析成类型的实例。

1.2序列化的作用

传递数据
保存数据(持久化数据)

1.3.NET中序列化的流程

  1. 将支持序列化的类型进行实例化成对象。
  2. 通过使用Formatter/Serializer将被序列化对象进行序列化编码。
  3. 然后存入指定的流中。

参与序列化过程的对象详细说明:

  1. 被序列化的对象
    可以是一个对象,也可是一个集合
    需要被序列化的类型需要使用SerializableAttribute 特性修饰
    类型中不可序列化的成员需要使用NonSerializedAttribute 特性修饰

  2. 包含已序列化对象的流对象
    比如:文件流、内存流

  3. Fromatter/Serializer类型
    用于给被序列化的对象进行序列化
    序列化和反序列化对象所使用的Fromatter/Serializer主要是以下类型

System.Text.Json.JsonSerializer
System.Xml.Serialization.XmlSerializer
System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
System.Runtime.Serialization.DataContractSerializer
System.Runtime.Serialization.Json.DataContractJsonSerializer

1.4序列化常用的底层格式

JSON(JavaScript Object Notation)
比较紧凑,适合用于传输
现在常用于Web传输数据

XML(eXtensible Markup Language)
表示数据更加直观,可读性更好
但也导致容量更大

Binary
在二进制序列化中,所有内容都会被序列化
使用二进制编码来生成精简的序列化
可以用于基于存储或socket的网络流

二、JSON序列化

2.1使用方法

使用方法相当简单,直接使用JsonSerializer静态类。
调用Serialize()静态方法进行序列化

JsonSerializer.Serialize()

调用Deserialize()静态方法进行反序列化

JsonSerializer.Deserialize()

2.2实例:序列化与反序列化

using System;
using System.IO;
using System.Text.Json;

namespace Demo
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
    
    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //进行序列化   string serializeString = JsonSerializer.Serialize(student,typeof(Student));
            Console.WriteLine(serializeString);

            //反序列化数据
            Student deserializedData = (Student)JsonSerializer.Deserialize(serializeString, typeof(Student));
            Console.WriteLine(deserializedData.Id);
            Console.WriteLine(deserializedData.Name);
            Console.WriteLine(deserializedData.Age);

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

三、JSON序列化(数据协定)

3.1使用方法

引入命名空间

using System.Runtime.Serialization.Json;

使用DataContractJsonSerializer类型

DataContractJsonSerializer

3.2实例:序列化数据

using System;
using System.IO;
using System.Runtime.Serialization.Json;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.json";
            using(FileStream fileStream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Student));

                //进行序列化
                dataContractJsonSerializer.WriteObject(fileStream, student);
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

3.3实例:反序列化数据

using System;
using System.IO;
using System.Runtime.Serialization.Json;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }
    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.json";
            using(FileStream fileStream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Student));

                //进行序列化
                dataContractJsonSerializer.WriteObject(fileStream, student);
            }

            //反序列化数据
            //新建文件流
            using (FileStream fileStream1 = new FileStream(filePath, FileMode.Open))
            {
                //新建序列化对象
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(Student));

                //进行反序列化
                Student student1 = (Student)dataContractJsonSerializer.ReadObject(fileStream1);

                //读取反序列化后的对象
                Console.WriteLine($"{student1.Id},{student1.Name},{student1.Age}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

四、XML序列化

4.1使用方法

所在命名空间

using System.Xml.Serialization;

使用XmlSerializer类型

XmlSerializer

注意:该类型只序列化public成员,非公共成员会发生异常。
注意:需要被序列化的类型必须有无参数的构造函数。
自定义集合类型成员的XML元素名称,使用[XmlArray]特性修改该成员即可

[XmlArray]
[XmlArrayItem]   //注意:修饰在和[XmlArray]同一个成员上

自定义XML元素的名称,使用特性修饰成员即可

[XmlRoot("RootName")]   指定根节点标签名称
[XmlElement("EleName")] 指定元素名称

将成员转为XML特性,使用特性修饰成员即可

[XmlAttribute("AtrrName")]

自定义XML命名空间,使用Namespace成员即可

[XmlRoot("RootName",Namespace = "Panda")]
[XmlAttribute("AtrrName", Namespace = "Panda")]
[XmlElement("EleName", Namespace = "Panda")]

4.2实例:序列化为XML

using System;
using System.IO;
using System.Xml.Serialization;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [NonSerialized]
        public int Age;
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //执行序列化
            //创建文件流
            string filePath = @"E:\xml.xml";
            using(FileStream fileStream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //创建XML序列化对象
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));
                //执行序列化
                xmlSerializer.Serialize(fileStream, student);
            }

            //执行反序列化
            //创建文件流
            using(FileStream fileStream1 = new FileStream(filePath,FileMode.Open))
            {
                //创建XML序列化对象
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));

                //执行反序列化
                Student data = (Student)xmlSerializer.Deserialize(fileStream1);

                //输出数据
                Console.WriteLine($"{data.Id},{data.Name},{data.Age}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

4.3实例:序列化为XML

using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace ConsoleApp6
{
    //测试用的类型
    public class Person
    {
        public Person()
        {

        }

        public Person(decimal initialSalary)
        {
            Salary = initialSalary;
        }

        public string FirstName { get; set; }

        public string LastName { get; set; }

        public DateTime DateOfBirth { get; set; }

        public HashSet<Person> Children { get; set; }

        protected decimal Salary { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //需要被序列化数据集合
            List<Person> people = new List<Person>
            {
                    new Person(30000M) { FirstName = "Alice",LastName = "Smith",
                    DateOfBirth = new DateTime(1974, 3, 14) },
                new Person(40000M) { FirstName = "Bob",LastName = "Jones",
                    DateOfBirth = new DateTime(1969, 11, 23) },
                new Person(20000M) { FirstName = "Charlie",LastName = "Cox",
                    DateOfBirth = new DateTime(1984, 5, 4),
                    Children = new HashSet<Person>
                    {   new Person(0M) { FirstName = "Sally",
                        LastName = "Cox",
                        DateOfBirth = new DateTime(2000, 7, 12) }
                    }
                }
            };

            //新建文件流
            //文件保存的位置
            string filePath = @"E:\xml.xml";
            using (FileStream stream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //新建序列化对象
                XmlSerializer xs = new XmlSerializer(typeof(List<Person>));

                //序列号集合数据到文件中
                xs.Serialize(stream, people);
            }

            //显示序列化后的内容
            Console.WriteLine(File.ReadAllText(filePath));

            //wait
            Console.ReadKey();
        }
    }
}

4.4实例:XML反序列化

using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace ConsoleApp6
{
    //测试用的类型
    public class Person
    {
        Person()
        {

        }

        public Person(decimal initialSalary)
        {
            Salary = initialSalary;
        }

        public string FirstName { get; set; }
        public string LastName { get; set; }
        public DateTime DateOfBirth { get; set; }
        public HashSet<Person> Children { get; set; }
        protected decimal Salary { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //文件保存的位置
            string filePath = @"E:\xml.xml";

            using (FileStream xmlLoad = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //序列化工具类
                XmlSerializer xs = new XmlSerializer(typeof(List<Person>));
                //执行反序列化操作
                var loadedPeople = (List<Person>)xs.Deserialize(xmlLoad);
                //输出数据内容
                foreach (var item in loadedPeople)
                {
                    Console.WriteLine("{0} has {1} children.", item.LastName, item.Children.Count);
                }
            }

            //wait
            Console.ReadKey();
        }
    }
}

4.5实例:自定义XML元素的名称/将成员转为XML特性/自定义XML命名空间

using System;
using System.IO;
using System.Collections.Generic;
using System.Xml.Serialization;

namespace ConsoleApp6
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    [XmlRoot("PandaRoot", Namespace = "panda666.com")]
    public class Student
    {
        public int Id { get; set; }
        [XmlElement("PandaElement", Namespace = "panda666.com")]
        public string Name { get; set; }
        [XmlAttribute("PandaAttribute", Namespace = "panda666.com")]
        public int Age;
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //执行序列化
            //创建文件流
            string filePath = @"E:\xml.xml";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //创建XML序列化对象
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));
                //执行序列化
                xmlSerializer.Serialize(fileStream, student);
            }

            //执行反序列化
            //创建文件流
            using (FileStream fileStream1 = new FileStream(filePath, FileMode.Open))
            {
                //创建XML序列化对象
                XmlSerializer xmlSerializer = new XmlSerializer(typeof(Student));

                //执行反序列化
                Student data = (Student)xmlSerializer.Deserialize(fileStream1);

                //输出数据
                Console.WriteLine($"{data.Id},{data.Name},{data.Age}");
            }

            //wait
            Console.ReadKey();
        }
    }
}

五、二进制序列化

5.1使用方法

在需要支持序列化的类型上使用[Serializable]特性

[Serializable]

然后引入命名空间

using System.Runtime.Serialization.Formatters.Binary;

然后使用BinaryFormatter类型

BinaryFormatter binaryFormatter = new BinaryFormatter();

标记无需序列化的字段,使用[NonSerialized]特性修饰字段即可

[NonSerialized]

注意:BinaryFormatter类型在.NET 5中已经被标记为废弃,考虑使用JsonSerializer或XmlSerializer代替BinaryFormatter。

5.2实例:二进制序列化

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //新建文件流
            string filePath = @"E:\新建文本文档.txt";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建二进制序列化对象
                BinaryFormatter binaryFormatter = new BinaryFormatter();

                //进行序列化
                binaryFormatter.Serialize(fileStream, student);
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

5.3实例:二进制反序列化

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //新建文件流
            string filePath = @"E:\新建文本文档.txt";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建二进制序列化对象
                BinaryFormatter binaryFormatter = new BinaryFormatter();

                //进行序列化
                binaryFormatter.Serialize(fileStream, student);
            }

            //新建文件流
            using(FileStream fileStream1 = new FileStream(filePath,FileMode.Open))
            {
                //新建二进制序列化对象
                BinaryFormatter binaryFormatter = new BinaryFormatter();

                //进行反序列化
                Student student1 = (Student)binaryFormatter.Deserialize(fileStream1);

                //输出反序列化的内容
                Console.WriteLine($"{student1.Id},{student1.Name},{student1.Age}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

5.4实例:标记无需序列化

using System;
using System.IO;
using System.Runtime.Serialization.Formatters.Binary;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        [NonSerialized]
        public int Age;
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //新建文件流
            string filePath = @"E:\新建文本文档.txt";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建二进制序列化对象
                BinaryFormatter binaryFormatter = new BinaryFormatter();

                //进行序列化
                binaryFormatter.Serialize(fileStream, student);
            }

            //新建文件流
            using (FileStream fileStream1 = new FileStream(filePath, FileMode.Open))
            {
                //新建二进制序列化对象
                BinaryFormatter binaryFormatter = new BinaryFormatter();

                //进行反序列化
                Student student1 = (Student)binaryFormatter.Deserialize(fileStream1);

                //输出反序列化的内容
                Console.WriteLine($"{student1.Id},{student1.Name},{student1.Age}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

六、数据协定类型序列化

6.1数据协定说明

数据协定方式进行序列化和反序列化的优点:

  1. 不同的类型之间可以进行序列化和反序列化操作。
  2. 实现跨网络、跨平台、跨应用进行数据通信。

6.2使用方法

6.2.1基本使用

引入命名空间

using System.Runtime.Serialization;

直接使用DataContractSerializer类型进行序列化操作即可。

DataContractSerializer

注意:DataContractSerializer类型底层使用XML格式数据。如果需要在底层使用JSON格式数据,需要使用DataContractJsonSerializer。

DataContractJsonSerializer

DataContractJsonSerializer所在命名空间。

using System.Runtime.Serialization.Json;
6.2.2统一数据格式

所在命名空间

using System.Runtime.Serialization;

在需要序列化的类型上使用特性

[DataContract(Name = "PandaItem", Namespace = "panda666.com")]

在需要序列化的类型的成员上使用特性

[DataMember(Name = "PandaName")]

在不需要序列化的成员上使用特性

[IgnoreDataMember]

如需指定成员序列化的顺序,可以使用特性的Order成员

[DataMember(Name = "PandaId",Order = 1)]
6.2.3保留引用实例

对于多个数据重复引用,可以使用保留引用实例来减少数据的生成量。
注意:仅在底层是XML序列化中有效。

//新建序列化配置对象
DataContractSerializerSettings settings = new DataContractSerializerSettings();

//开启保留引用实例
settings.PreserveObjectReferences = true;

//新建序列化对
DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(PandaClass), settings);

6.3实例:序列化数据

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.txt";
            using(FileStream fileStream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(Student));

                //进行序列化
                dataContractSerializer.WriteObject(fileStream, student);
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

6.4实例:反序列化数据

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型
    /// </summary>
    [Serializable]
    public class Student
    {
        public int Id { get; set; }
        public string Name { get; set; }
        public int Age { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            Student student = new Student()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.txt";
            using(FileStream fileStream = new FileStream(filePath,FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(Student));

                //进行序列化
                dataContractSerializer.WriteObject(fileStream, student);
            }

            //反序列化数据
            //新建文件流
            using (FileStream fileStream1 = new FileStream(filePath,FileMode.Open))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(Student));

                //进行反序列化
                Student student1 = (Student)dataContractSerializer.ReadObject(fileStream1);

                //输出反序列化的内容
                Console.WriteLine($"{student1.Id},{student1.Name},{student1.Age}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

6.5实例:跨类型进行序列化

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型1
    /// </summary>
    [DataContract(Name = "PandaItem", Namespace = "panda666.com")]
    public class PandaClass
    {
        [DataMember(Name = "PandaId")]
        public int Id { get; set; }
        [DataMember(Name = "PandaName")]
        public string Name { get; set; }
        [DataMember(Name = "PandaAge")]
        public int Age { get; set; }
    }

    /// <summary>
    /// 测试使用的类型2
    /// </summary>
    [DataContract(Name = "PandaItem", Namespace = "panda666.com")]
    public class PandaClass2
    {
        [DataMember(Name = "PandaId")]
        public int PandaId { get; set; }
        [DataMember(Name = "PandaName")]
        public string PandaName { get; set; }
        [DataMember(Name = "PandaAge")]
        public int PandaAge { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            PandaClass panda = new PandaClass()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.xml";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(PandaClass));

                //进行序列化
                dataContractSerializer.WriteObject(fileStream, panda);
            }

            //反序列化数据
            using(FileStream fileStream1 = new FileStream(filePath,FileMode.Open))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(PandaClass2));

                //进行反序列化
                PandaClass2 data = (PandaClass2)dataContractSerializer.ReadObject(fileStream1);

                //输出数据
                Console.WriteLine($"{data.PandaId},{data.PandaName},{data.PandaAge}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

6.6实例:开启保留引用实例

using System;
using System.IO;
using System.Runtime.Serialization;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型1
    /// </summary>
    [DataContract(Name = "PandaItem", Namespace = "panda666.com")]
    public class PandaClass
    {
        [DataMember(Name = "PandaId")]
        public int Id { get; set; }
        [DataMember(Name = "PandaName")]
        public string Name { get; set; }
        [DataMember(Name = "PandaAge")]
        public int Age { get; set; }
    }

    /// <summary>
    /// 测试使用的类型2
    /// </summary>
    [DataContract(Name = "PandaItem", Namespace = "panda666.com")]
    public class PandaClass2
    {
        [DataMember(Name = "PandaId")]
        public int PandaId { get; set; }
        [DataMember(Name = "PandaName")]
        public string PandaName { get; set; }
        [DataMember(Name = "PandaAge")]
        public int PandaAge { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            PandaClass panda = new PandaClass()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.xml";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建序列化配置对象
                DataContractSerializerSettings settings = new DataContractSerializerSettings();
                //开启保留引用实例
                settings.PreserveObjectReferences = true;

                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(PandaClass), settings);

                //进行序列化
                dataContractSerializer.WriteObject(fileStream, panda);
            }

            //反序列化数据
            using (FileStream fileStream1 = new FileStream(filePath, FileMode.Open))
            {
                //新建序列化对象
                DataContractSerializer dataContractSerializer = new DataContractSerializer(typeof(PandaClass2));

                //进行反序列化
                PandaClass2 data = (PandaClass2)dataContractSerializer.ReadObject(fileStream1);

                //输出数据
                Console.WriteLine($"{data.PandaId},{data.PandaName},{data.PandaAge}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}

6.7实例:跨类型进行序列化(底层JSON)

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Json;

namespace ConsoleApp1
{
    /// <summary>
    /// 测试使用的类型1
    /// </summary>
    [DataContract(Name = "PandaItem")]
    public class PandaClass
    {
        [DataMember(Name = "PandaId")]
        public int Id { get; set; }
        [DataMember(Name = "PandaName")]
        public string Name { get; set; }
        [DataMember(Name = "PandaAge")]
        public int Age { get; set; }
    }

    /// <summary>
    /// 测试使用的类型2
    /// </summary>
    [DataContract(Name = "PandaItem")]
    public class PandaClass2
    {
        [DataMember(Name = "PandaId")]
        public int PandaId { get; set; }
        [DataMember(Name = "PandaName")]
        public string PandaName { get; set; }
        [DataMember(Name = "PandaAge")]
        public int PandaAge { get; set; }
    }

    class Program
    {
        static void Main(string[] args)
        {
            //新建类型实例
            PandaClass panda = new PandaClass()
            {
                Id = 666,
                Name = "Panda",
                Age = 666666
            };

            //序列化数据
            //新建文件流
            string filePath = @"E:\新建文本文档.json";
            using (FileStream fileStream = new FileStream(filePath, FileMode.OpenOrCreate))
            {
                //新建序列化对象
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(PandaClass));

                //进行序列化
                dataContractJsonSerializer.WriteObject(fileStream, panda);
            }


            //反序列化数据
            using (FileStream fileStream1 = new FileStream(filePath, FileMode.Open))
            {
                //新建序列化对象
                DataContractJsonSerializer dataContractJsonSerializer = new DataContractJsonSerializer(typeof(PandaClass2));

                //进行反序列化
                PandaClass2 data = (PandaClass2)dataContractJsonSerializer.ReadObject(fileStream1);

                //输出数据
                Console.WriteLine($"{data.PandaId},{data.PandaName},{data.PandaAge}");
            }

            //wait
            Console.WriteLine("Success");
            Console.ReadKey();
        }
    }
}
posted @ 2022-04-16 17:11  重庆熊猫  阅读(5857)  评论(0编辑  收藏  举报