最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

徹底掌握.NET中序列化反序列化問題及避坑指南

 更新時間:2025年12月22日 09:20:48   作者:武藤一雄  
本文詳細探討了二進制序列化、JSON序列化、XML序列化以及它們在不同場景下的應(yīng)用,此外,還提到了一些序列化過程中需要注意的問題,如性能優(yōu)化和循環(huán)引用處理,感興趣的朋友跟隨小編一起看看吧

在 .NET 領(lǐng)域,序列化(Serialization)簡單來說就是把對象“拍扁”成一段數(shù)據(jù)流(如二進制、XML、JSON),以便存到硬盤或通過網(wǎng)絡(luò)發(fā)給別人。反序列化(Deserialization)則是把這段流“吹氣”還原成內(nèi)存里的 C# 對象。

序列化是把一個內(nèi)存中的對象的信息轉(zhuǎn)化成一個可以持久化保存的形式,以便于保存或傳輸,序列化的主要作用是不同平臺之間進行通信,常用的有序列化有json、xml、文件等,下面就逐個講下這三種序列化的方法。

在 C# 開發(fā)中,你主要會接觸到以下三種類型的序列化方式:

注意:原生的 BinaryFormatter 因為存在嚴(yán)重的安全漏洞,微軟已經(jīng)在 .NET 5+ 以后將其標(biāo)注為過時(Deprecated),千萬不要在生產(chǎn)環(huán)境使用它。

對象的序列化主要有兩種用途

1.把對象的字節(jié)序列永久地保存到硬盤上,通常存放在一個文件中

我們經(jīng)常需要將對象的字段值保存到磁盤中,并在以后檢索此數(shù)據(jù)。盡管不使用序列化也能完成這項工作,但這種方法通常很繁瑣而且容易出錯,并且在需要跟蹤對象的層次結(jié)構(gòu)時,會變得越來越復(fù)雜。

可以想象一下編寫包含大量對象的大型業(yè)務(wù)應(yīng)用程序的情形,程序員不得不為每一個對象編寫代碼,以便將字段和屬性保存至磁盤以及從磁 盤還原這些字段和屬性。序列化提供了輕松實現(xiàn)這個目標(biāo)的快捷方法。公共語言運行時 (CLR) 管理對象在內(nèi)存中的分布,.NET 框架則通過使用反射提供自動的序列化機制。對象序列化后,類的名稱、程序集以及類實例的所有數(shù)據(jù)成員均被寫入存儲媒體中。對象通常用成員變量來存儲對其他實例的引用。類序列化后,序列化引擎將跟蹤所有已序列化的引用對象,以確保同一對象不被序列化多次。

.NET 框架所提供的序列化體系結(jié)構(gòu)可以自動正確處理對象圖表和循環(huán)引用。對對象圖表的唯一要求是,由正在進行序列化的對象所引用的所有對象都必須標(biāo)記為 Serializable(請參閱基 本序列化)。否則,當(dāng)序列化程序試圖序列化未標(biāo)記的對象時將會出現(xiàn)異常。當(dāng)反序列化已序列化的類時,將重新創(chuàng)建該類,并自動還原所有數(shù)據(jù)成員的值。

2.在網(wǎng)絡(luò)上傳送對象的字節(jié)序列

對象僅在創(chuàng)建對象的應(yīng)用程序域中有效。除非對象是從MarshalByRefObject派生得到或標(biāo)記為 Serializable,否則,任何將對象作為參數(shù)傳遞或?qū)⑵渥鳛榻Y(jié)果返回的嘗試都將失敗。

如果對象標(biāo)記為 Serializable,則該對象將被自動序列化,并從一個應(yīng)用程序域傳輸至另一個應(yīng)用程序域,然后進行反序列化,從而在第二個應(yīng)用程序域中產(chǎn)生出該對象的一個精確副本。此過程通常稱為按值封送。如果對象是從MarshalByRefObject派生得到,則從一個應(yīng)用程序域傳遞至另一個應(yīng)用程序域的是對象引用,而不是對象本身。也可以將從MarshalByRefObject派生得到的對象標(biāo)記為Serializable。

3.序列化和反序列化的主要作用有

  1. 在進程下次啟動時讀取上次保存的對象的信息
  2. 在不同的AppDomain或進程之間傳遞數(shù)據(jù)
  3. 在分布式應(yīng)用系統(tǒng)中傳遞數(shù)據(jù)

什么叫序列化?

我們都知道對象是暫時保存在內(nèi)存中的,不能用U盤考走了,有時為了使用介質(zhì)轉(zhuǎn)移對象,并且把對象的狀態(tài)保持下來,就需要把對象保存下來,這個過程就叫做序列化,通俗點,就是把人的魂(對象)收伏成一個魂器(可傳輸?shù)慕橘|(zhì)

什么叫反序列化?

就是再把介質(zhì)中的東西還原成對象,把魂器還原成人的過程。

在進行這些操作的時候都需要這個可以被序列化,要能被序列化,就得給類頭加[Serializable]特性。通常網(wǎng)絡(luò)程序為了傳輸安全才這么做。

序列化及反序列化

C#中用于對象和json相互轉(zhuǎn)換的原生類有兩個:

DataContractJsonSerializer

JavaScriptSerializer,

其中JavaScriptSerializer主要用于web的瀏覽器和服務(wù)器之間的通信。

這里主要講DataContractJsonSerializer的使用,要使用DataContractJsonSerializer,先要在項目中引用System.Runtime.Serialization。首先準(zhǔn)備一個測試的類Book:

二進制序列化

序列化為二進制

[Serializable]

1、Serializable特性的作用

序列化的attribute,是為了利用序列化的技術(shù) 準(zhǔn)備用于序列化的對象必須設(shè)置 [System.Serializable] 標(biāo)簽,該標(biāo)簽指示一個類可以序列化。 便于在網(wǎng)絡(luò)中傳輸和保存這個標(biāo)簽是類可以被序列化的特性,表示這個類可以被序列化。

[Serializable]
public class Student
{
   public string Name { get; set; }
   public int Sex { get; set; }
   public int Age { get; set; }
   public Address Address { get; set; }
}
[Serializable]
public class Address
{
   public string City { get; set; }
   public string Road { get; set; }
}

上述代碼中我們在類的頭部加入了 Serializable 特性,這代表著整個類對象都需要序列化,如果我們不需要序列化其中某個屬性的話只需在該屬性上加上 NonSerialized 特性即可。下面我們來看一下序列化和反序列化的代碼:

class Program
{
    static void Main(string[] args)
    {
        #region 序列化
        Student student = new Student
        {
            Name = "Tom",
            Age = 20,
            Sex = 1,
            Address = new Address
            {
                City = "NYC",
                Road = "ABC"
            }
        };
        //二進制序列化
        BinaryFormatter binFormat = new BinaryFormatter();
        //返回保存的文檔
        string fileName = Path.Combine(@"D:\", @"321.txt");
        using (Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite))
        {
            binFormat.Serialize(fStream, student);
        }
        #endregion
        #region 反序列化
        using (Stream fStream = new FileStream(fileName, FileMode.Open, FileAccess.ReadWrite))
        {
            fStream.Position = 0;
            student = (Student)binFormat.Deserialize(fStream);
        }
        Console.WriteLine("Name: " + student.Name);
        Console.WriteLine("Sex: " + student.Sex);
        Console.WriteLine("Age: " + student.Age);
        Console.WriteLine("Address: " + student.Address.City + " " + student.Address.Road);
        #endregion
        Console.ReadLine();
    }
}

第二種寫法

using System;
using System.Collections;
using System.IO;
using System.Collections.Generic;
using System.Runtime.Serialization.Formatters.Binary;
using System.Diagnostics;
namespace ConsoleApp1
{
	[Serializable]      // 表示該類可以被序列化
	class Person
	{
		private string name;
		[NonSerialized]  // 表示下面這個age字段不進行序列化
		private int age;
		public string Name
		{
			get { return name; }
			set { name = value; }
		}
		public int Age
		{
			get { return age; }
			set { age = value; }
		}
		public Person() { }
		public Person(string name, int age)
		{
			this.name = name;
			this.age = age;
		}
		public void SayHi()
		{
			Console.WriteLine("我是{0}, 今年{1}歲", name, age);
		}
	}
		class Program
		{
			static void Main(string[] args)
			{
			string filePath = Path.Combine(@"D:\", @"321.txt");
			// Use this for initialization
				List<Person> listPers = new List<Person>();
				Person per1 = new Person("張三", 18);
				Person per2 = new Person("李四", 20);
				listPers.Add(per1);
				listPers.Add(per2);
				SerializeMethod(listPers, filePath);  // 序列化
				DeserializeMethod();  // 反序列化
				Console.WriteLine("Done ! ");
				Console.ReadKey();
			void DeserializeMethod()     // 二進制反序列化
			{
				FileStream fs = new FileStream(filePath, FileMode.Open);
				BinaryFormatter bf = new BinaryFormatter();
				List<Person> list = bf.Deserialize(fs) as List<Person>;
				if (list != null)
				{
					for (int i = 0; i < list.Count; i++)
					{
						list[i].SayHi();
					}
				}
				fs.Close();
			}
		}
        private static void SerializeMethod(List<Person> listPers, string filePath)
        {
            FileStream fs = new FileStream(filePath, FileMode.Create);
            BinaryFormatter bf = new BinaryFormatter();
            bf.Serialize(fs, listPers);
            fs.Close();
        }
    }
}

寫法三

using System;
using System.IO;
using System.Runtime.Serialization;
using System.Runtime.Serialization.Formatters.Binary;
namespace SerializableTest
{
    class Program
    {
        static void Main(string[] args)
        {
            //創(chuàng)建一個格式化程序的實例
            IFormatter formatter = new BinaryFormatter();
            Console.WriteLine("對象序列化開始……");
            var me = new Person
                         {
                             Sno = "200719",
                             Name = "yuananyun",
                             Sex="man",
                             Age=22
                         };
            //創(chuàng)建一個文件流
            Stream stream = new FileStream("c:/personInfo.txt", FileMode.OpenOrCreate, FileAccess.Write, FileShare.None);
            formatter.Serialize(stream, me);
            stream.Close();
            Console.WriteLine("序列化結(jié)束!\n");
            Console.WriteLine("反序列化開始……");
            //反序列化
            Stream destream = new FileStream("c:/personInfo.txt", FileMode.Open,
            FileAccess.Read, FileShare.Read);
            var stillme = (Person)formatter.Deserialize(destream);
            stream.Close();
            Console.WriteLine("反序列化結(jié)束,輸出對象信息……");
            Console.WriteLine(stillme.DisplayInfo());
            Console.ReadKey();
        }
    }
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace SerializableTest
{
    [Serializable]
    public class Person
    {
        public string Sno { get; set; }
        public string Name { get; set; }
        public string Sex { get; set; }
        public int Age { get; set; }
        public string DisplayInfo()
        {
            return "我的學(xué)號是:" +Sno+ "\n我的名字是:"+Name + "\n我的性別為:"+Sex+"\n我的年齡:"+Age+"\n";
        }
    }
}

JSON

JSON 的英文全稱是 JavaScript Object Notation ,是一種輕量級的數(shù)據(jù)交換格式。完全獨立于語言的文本格式 易于人閱讀和編寫同時也易于機器解析和生成。JSON 是目前互聯(lián)網(wǎng)中主流的數(shù)據(jù)交換格式,同時也是很多開發(fā)語言配置文件的主流格式。

  1. 在 .NET 中存在兩個類對 JSON 進行處理,分別是 DataContractJsonSerializer 和 JavaScriptSerializer ,這兩個類的功能基本一致。 DataContractJsonSerializer 位于命名空間 System.Runtime.Serialization.Json 下,它的特點是必須使用 DataContract 以及 DataMember 屬性標(biāo)記成員。 JavaScriptSerializer 位于命名空間 System.Web.Script.Serialization 下,通過名字和它所在的命名空間我們可以得知它主要用在網(wǎng)絡(luò)通信中,它可以序列化任何類型的對象。同樣 .NET 中也存在一個強大的第三方 JSON 序列化/反序列化庫 Newtonsoft.Json ,他比前兩個類用起來要方便很多。下面我們對這三個序列化/反序列化的方式分別進行講解。

DataContractJsonSerializer

  • 首先我們需要在項目中引用 DataContractJsonSerializer 所在的命名空間,這里要注意的時我們不僅要在項目中添加引用 System.Runtime.Serialization 還需要添加引用 System.ServiceModel.Web 。將這兩個命名空添加到命名空間后就可以在代碼中引入 DataContractJsonSerializer 的命名空間了。

Json支持下面兩種數(shù)據(jù)結(jié)構(gòu):

  • 鍵值對的集合–各種不同的編程語言,都支持這種數(shù)據(jù)結(jié)構(gòu);
  • 有序的列表類型值的集合–這其中包含數(shù)組,集合,矢量,或者序列,等等。

Json有下面幾種表現(xiàn)形式

1.對象

一個沒有順序的“鍵/值”,一個對象以花括號“{”開始,并以花括號"}"結(jié)束,在每一個“鍵”的后面,有一個冒號,并且使用逗號來分隔多個鍵值對。例如:

var user = {“name”:“Manas”,“gender”:“Male”,“birthday”:“1987-8-8”}

2.數(shù)組

設(shè)置值的順序,一個數(shù)組以中括號"[“開始,并以中括號”]"結(jié)束,并且所有的值使用逗號分隔,例如:

var userlist = [{“user”:{“name”:“Manas”,“gender”:“Male”,“birthday”:“1987-8-8”}},{“user”:{“name”:“Mohapatra”,“Male”:“Female”,“birthday”:“1987-7-7”}}]

3.字符串

任意數(shù)量的Unicode字符,使用引號做標(biāo)記,并使用反斜杠來分隔。例如:

  • var userlist = “{“ID”:1,“Name”:“Manas”,“Address”:“India”}”
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Runtime.Serialization;
namespace JsonSerializerAndDeSerializer
{
    [DataContract]
   public class Student
    {
        [DataMember]
       public int ID { get; set; }
        [DataMember]
       public string Name { get; set; }
        [DataMember]
       public int Age { get; set; }
        [DataMember]
       public string Sex { get; set; }
    }
}

數(shù)據(jù)契約(DataContract) 服務(wù)契約定義了遠程訪問對象和可供調(diào)用的方法,數(shù)據(jù)契約則是服務(wù)端和客戶端之間要傳送的自定義數(shù)據(jù)類型。一旦聲明一個類型為DataContract,那么該類型就可以被序列化在服務(wù)端和客戶端之間傳送

只有聲明為DataContract的類型的對象可以被傳送,且只有成員屬性會被傳遞,成員方法不會被傳遞。默認(rèn)情況下類中的所有成員屬性都不會被序列化傳輸出去,如果需要將成員數(shù)據(jù)傳輸出去就需要在屬性頭部加入 DataMember

1.DataContractJsonSerializer

DataContractJsonSerializer類幫助我們序列化和反序列化Json,他在程序集 System.Runtime.Serialization.dll下的System.Runtime.Serialization.Json命名空間里。

  Student stu = new Student()
             {
                 ID = 1,
                 Name = "曹操",
                 Sex = "男",
                 Age = 1000
             };
            //序列化
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Student));
            MemoryStream msObj = new MemoryStream();
            //將序列化之后的Json格式數(shù)據(jù)寫入流中
            js.WriteObject(msObj, stu);
            msObj.Position = 0;
            //從0這個位置開始讀取流中的數(shù)據(jù)
            StreamReader sr = new StreamReader(msObj, Encoding.UTF8);
            string json = sr.ReadToEnd();
            sr.Close();
            msObj.Close();
            Console.WriteLine(json);
            //反序列化
            string toDes = json;
            //string to = "{\"ID\":\"1\",\"Name\":\"曹操\",\"Sex\":\"男\(zhòng)",\"Age\":\"1230\"}";
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(toDes)))
            {
                DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(Student));
                Student model = (Student)deseralizer.ReadObject(ms);// //反序列化ReadObject
                Console.WriteLine("ID=" + model.ID);
                Console.WriteLine("Name=" + model.Name);
                Console.WriteLine("Age=" + model.Age);
                Console.WriteLine("Sex=" + model.Sex);
            }
            Console.ReadKey();
  Student stu = new Student()
             {
                 ID = 1,
                 Name = "曹操",
                 Sex = "男",
                 Age = 1000
             };
            //序列化
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Student));
            MemoryStream msObj = new MemoryStream();
            //將序列化之后的Json格式數(shù)據(jù)寫入流中
            js.WriteObject(msObj, stu);
            msObj.Position = 0;
            //從0這個位置開始讀取流中的數(shù)據(jù)
            StreamReader sr = new StreamReader(msObj, Encoding.UTF8);
            string json = sr.ReadToEnd();
            sr.Close();
            msObj.Close();
            Console.WriteLine(json);
            //反序列化
            string toDes = json;
            //string to = "{\"ID\":\"1\",\"Name\":\"曹操\",\"Sex\":\"男\(zhòng)",\"Age\":\"1230\"}";
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(toDes)))
            {
                DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(Student));
                Student model = (Student)deseralizer.ReadObject(ms);// //反序列化ReadObject
                Console.WriteLine("ID=" + model.ID);
                Console.WriteLine("Name=" + model.Name);
                Console.WriteLine("Age=" + model.Age);
                Console.WriteLine("Sex=" + model.Sex);
            }
            Console.ReadKey();
  Student stu = new Student()
             {
                 ID = 1,
                 Name = "曹操",
                 Sex = "男",
                 Age = 1000
             };
            //序列化
            DataContractJsonSerializer js = new DataContractJsonSerializer(typeof(Student));
            MemoryStream msObj = new MemoryStream();
            //將序列化之后的Json格式數(shù)據(jù)寫入流中
            js.WriteObject(msObj, stu);
            msObj.Position = 0;
            //從0這個位置開始讀取流中的數(shù)據(jù)
            StreamReader sr = new StreamReader(msObj, Encoding.UTF8);
            string json = sr.ReadToEnd();
            sr.Close();
            msObj.Close();
            Console.WriteLine(json);
            //反序列化
            string toDes = json;
            //string to = "{\"ID\":\"1\",\"Name\":\"曹操\",\"Sex\":\"男\(zhòng)",\"Age\":\"1230\"}";
            using (var ms = new MemoryStream(Encoding.Unicode.GetBytes(toDes)))
            {
                DataContractJsonSerializer deseralizer = new DataContractJsonSerializer(typeof(Student));
                Student model = (Student)deseralizer.ReadObject(ms);// //反序列化ReadObject
                Console.WriteLine("ID=" + model.ID);
                Console.WriteLine("Name=" + model.Name);
                Console.WriteLine("Age=" + model.Age);
                Console.WriteLine("Sex=" + model.Sex);
            }
            Console.ReadKey();

2.JavaScriptJsonSerializer

Student stu = new Student()
{
ID = 1,
Name = "關(guān)羽",
Age = 2000,
Sex = "男"
};
JavaScriptSerializer js = new JavaScriptSerializer();
string jsonData = js.Serialize(stu);//序列化
Console.WriteLine(jsonData);
////反序列化方式一:
string desJson = jsonData;
//Student model = js.Deserialize<Student>(desJson);// //反序列化
//string message = string.Format("ID={0},Name={1},Age={2},Sex={3}", model.ID, model.Name, model.Age, model.Sex);
//Console.WriteLine(message);
//Console.ReadKey();
////反序列化方式2
dynamic modelDy = js.Deserialize<dynamic>(desJson); //反序列化
string messageDy = string.Format("動態(tài)的反序列化,ID={0},Name={1},Age={2},Sex={3}",
modelDy["ID"], modelDy["Name"], modelDy["Age"], modelDy["Sex"]);//這里要使用索引取值,不能使用對象.屬性
Console.WriteLine(messageDy);
Console.ReadKey();

3.JSON.NET(性能最好)

List<Student> lstStuModel = new List<Student>()
{
new Student(){ID=1,Name="張飛",Age=250,Sex="男"},
new Student(){ID=2,Name="潘金蓮",Age=300,Sex="女"}
};
//Json.NET序列化
string jsonData = JsonConvert.SerializeObject(lstStuModel);
Console.WriteLine(jsonData);
Console.ReadKey();
//Json.NET反序列化
string json = @"{ 'Name':'C#','Age':'3000','ID':'1','Sex':'女'}";
Student descJsonStu = JsonConvert.DeserializeObject<Student>(json);//反序列化
Console.WriteLine(string.Format("反序列化: ID={0},Name={1},Sex={2},Sex={3}", descJsonStu.ID, descJsonStu.Name, descJsonStu.Age, descJsonStu.Sex));
Console.ReadKey();

XML

UTF-8

互聯(lián)網(wǎng)的普及,強烈要求出現(xiàn)一種統(tǒng)一的編碼方式。UTF-8 就是在互聯(lián)網(wǎng)上使用最廣的一種 Unicode 的實現(xiàn)方式。其他實現(xiàn)方式還包括 UTF-16(字符用兩個字節(jié)或四個字節(jié)表示)和 UTF-32(字符用四個字節(jié)表示),不過在互聯(lián)網(wǎng)上基本不用。重復(fù)一遍,這里的關(guān)系是,UTF-8 是 Unicode 的實現(xiàn)方式之一。

UTF-8 最大的一個特點,就是它是一種變長的編碼方式。它可以使用1~4個字節(jié)表示一個符號,根據(jù)不同的符號而變化字節(jié)長度。

UTF-8 的編碼規(guī)則很簡單,只有二條:

1)對于單字節(jié)的符號,字節(jié)的第一位設(shè)為0,后面7位為這個符號的 Unicode 碼。因此對于英語字母,UTF-8 編碼和 ASCII 碼是相同的。

2)對于n字節(jié)的符號(n > 1),第一個字節(jié)的前n位都設(shè)為1,第n + 1位設(shè)為0,后面字節(jié)的前兩位一律設(shè)為10。剩下的沒有提及的二進制位,全部為這個符號的 Unicode 碼。

下表總結(jié)了編碼規(guī)則,字母x表示可用編碼的位。

XML和JSON比較

SON 和 XML 都用于接收 web 服務(wù)端的數(shù)據(jù)。

JSON 和 XML在寫法上有所不同,如下所示:

JSON 實例

{
    "sites": [
    { "name":"菜鳥教程" , "url":"www.runoob.com" },
    { "name":"google" , "url":"www.google.com" },
    { "name":"微博" , "url":"www.weibo.com" }
    ]
}

XML 實例

<sites>
  <site>
    <name>菜鳥教程</name> <url>www.runoob.com</url>
  </site>
  <site>
    <name>google</name> <url>www.google.com</url>
  </site>
  <site>
    <name>微博</name> <url>www.weibo.com</url>
  </site>
</sites>

JSON 與 XML 的相同之處:

  • JSON 和 XML 數(shù)據(jù)都是 “自我描述” ,都易于理解。
  • JSON 和 XML 數(shù)據(jù)都是有層次的結(jié)構(gòu)
  • JSON 和 XML 數(shù)據(jù)可以被大多數(shù)編程語言使用

JSON 與 XML 的不同之處:

  • JSON 不需要結(jié)束標(biāo)簽
  • JSON 更加簡短
  • JSON 讀寫速度更快
  • JSON 可以使用數(shù)組

最大的不同是:XML 需要使用 XML 解析器來解析,JSON 可以使用標(biāo)準(zhǔn)的 JavaScript 函數(shù)來解析。

JSON.parse(): 將一個 JSON 字符串轉(zhuǎn)換為 JavaScript 對象。

JSON.stringify(): 于將 JavaScript 值轉(zhuǎn)換為 JSON 字符串。

為什么 JSON 比 XML 更好?

XML 比 JSON 更難解析。

JSON 可以直接使用現(xiàn)有的 JavaScript 對象解析。

針對 AJAX 應(yīng)用,JSON 比 XML 數(shù)據(jù)加載更快,而且更簡單:

使用 XML

  • 獲取 XML 文檔
  • 使用 XML DOM 迭代循環(huán)文檔
  • 接數(shù)據(jù)解析出來復(fù)制給變量

使用 JSON

  • 獲取 JSON 字符串
  • JSON.Parse 解析 JSON 字符串

避坑指南

特性(Attribute)控制

通過給類成員打標(biāo)簽,可以精確控制序列化行為:

  • [JsonIgnore]:不參與序列化,常用于保護敏感數(shù)據(jù)或防止循環(huán)引用。
  • [JsonPropertyName]:當(dāng) C# 命名規(guī)范(大駝峰)和 JSON 規(guī)范(小駝峰/下劃線)沖突時做映射。

性能陷阱

  • 反射開銷:傳統(tǒng)的序列化器在運行時利用反射獲取類型信息,這很耗 CPU。
  • Source Generation (源生成器):.NET 6+ 引入了 JsonSourceGenerationOptions。它在編譯時就生成好序列化代碼,不再依賴反射,極大提升了 AOT(原生編譯)環(huán)境和高性能場景的啟動速度。

循環(huán)引用問題

如果 A 引用 B,B 又引用 A,序列化器會陷入死循環(huán)報錯。

  • 解法:在 JsonSerializerOptions 中設(shè)置 ReferenceHandler.Preserve

到此這篇關(guān)于徹底掌握.NET中序列化反序列化問題及避坑指南的文章就介紹到這了,更多相關(guān).net序列化反序列化內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

最新評論

栾川县| 涿鹿县| 无为县| 荣成市| 百色市| 安化县| 大田县| 鄯善县| 满城县| 静宁县| 习水县| 天祝| 江口县| 卫辉市| 新绛县| 略阳县| 剑河县| 云梦县| 临猗县| 会东县| 武城县| 调兵山市| 关岭| 金秀| 台前县| 平遥县| 海南省| 卫辉市| 岑巩县| 孝义市| 铜鼓县| 故城县| 微山县| 西安市| 吉水县| 湘西| 秭归县| 宝鸡市| 图木舒克市| 铁岭市| 巩义市|