.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();
        }
    }
}


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM