C# Serializer Attribute – 序列屬性使用教學
C# Serializer Attribute – 介紹
C# Serializer Attribute是一種特殊的屬性,用於控制類別或類別成員(如Property)的序列化行為。序列化(Serialize)是將物件轉換為可存儲或可傳輸格式(如 XML 或 JSON)的過程,而反序列化(Deserialize)則是相反的過程,即將這些格式轉換回原始物件。這在資料傳輸和持久化存儲時特別有用,尤其是在不同應用程式或服務之間交換資料時。
使用 Serializer 屬性,開發者可以精確控制哪些部分應被序列化或反序列化,甚至可以定義自定義的序列化邏輯。例如,可以通過屬性來指定某些敏感資料不應被序列化,或者調整序列化過程以優化性能。
此外,這些屬性也支持設定如何處理物件的不同狀態,比如處理循環引用或管理物件之間的關聯。這對於複雜物件圖的序列化尤其重要。
然而,使用這些屬性需要對序列化的細節有較深的理解,並可能增加代碼的複雜性。開發者在使用時需要在控制與複雜性之間權衡,並考慮到潛在的維護挑戰。
使用 C# Serializer Attribute 優點與缺點
下方是使用 C# Serializer Attribute 優點與缺點:
優點 | 缺點 |
---|---|
控制序列化過程:允許細節控制如何和何時序列化物件,可以指定哪些屬性被序列化。 | 複雜性增加:對於初學者或不熟悉序列化機制的開發者來說,可能增加理解和使用的複雜度。 |
安全性:透過指定特定屬性,可以防止敏感資料被意外序列化,增強資料安全。 | 維護成本:當類別結構變更時,相關的序列化代碼也需要更新,這可能增加維護成本。 |
效能優化:可以透過選擇性序列化來改善性能,特別是對於大型物件或複雜物件結構。 | 與平台的依賴性:特定的 Serializer 屬性可能與特定的.NET版本或平台緊密相連,可能影響跨平台兼容性。 |
靈活性:允許開發者自訂序列化邏輯,提供更多的靈活性來滿足特定需求。 | 測試複雜性:自定義序列化邏輯可能使單元測試更加複雜,需要更多的測試案例來確保序列化行為正確。 |
資料一致性:有助於保持資料格式的一致性,特別是在不同的應用程式或服務間交換資料時。 | 向後兼容性問題:在序列化屬性或方法變更時,可能會導致舊版本的應用程式無法正確解析新格式的資料。 |
工作上的經驗
在工作上常常會透過外部檔案來控制系統上內部資料,所以C# Serializer是很方便的工具,且不用額外的時間或人力去維護。但是當資料量過大無法一次性的,將資料放置記憶體內,則需要區域性或是分段性的存取方式,則無法透過C# Serializer的方式存取,因會對程序和記憶體造成過大的負擔,進而導致程序執行上的緩慢。
C# Serializer Attribute 操作範例:
操作步驟
- 定義Person為Serializable,可序列化的類別
- 定義序列化功能
- 定義反序列化功能
- 測試程式代碼
- 測試結果
下面提供實驗範例及程式碼:
1. 定義Person為Serializable,可序列化的類別
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 |
[Serializable] class Person { // Property to store a person's name public string Name { get; set; } // Property to store a person's ID with a custom name when serialized to JSON [JsonPropertyName("id")] public int ID { get; set; } // Property to format the person's name and ID, but will be ignored during JSON serialization [JsonIgnore] public string Formatter => $"{Name}: {ID}"; public override string ToString() { return Formatter; } } |
上方代碼說明如下:
- [Serializable]: 這是一個標籤,用於告訴 .NET runtime,此類別可以被序列化(即可以將其轉換為字串或其他格式)。
- class Person: 這是一個類別,它代表了一個人的物件。
- string Name { get; set; }: 用於存取人得名子。
- [JsonPropertyName(“id”)]: 這是一個 Json.NET 的標籤,用於對 JSON 序列化/反序列化過程中的 ID 屬性進行命名(‘id’) 。
- int ID { get; set; }:用於存儲人的身份識別碼。
- [JsonIgnore]: 這是一個 Json.NET 的標籤,用於告訴 JsonSerializer 忽略這個屬性(Formatter)的序列化/反序列化。
- public string Formatter => $”{Name}: {ID}”;:這是一個公共字符串屬性,它格式化了人的名字和身份證號。
2.1 定義序列化泛型類型
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
static function" >// SerializeObject is a generic method that can serialize any object to a JSON string and write it to a file. private static void SerializeObject<T>(string fileName, T Obj) { // Use a StreamWriter to write the JSON string to a file. using (var file = new StreamWriter(fileName)) { // Use JsonSerializer to serialize the object to a JSON string. var json = JsonSerializer.Serialize(Obj); // Write the JSON string to the file. file.Write(json); // Write the JSON string to the console. Console.WriteLine(json); } } |
2.2 定義單一序列化功能
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private static void SerializePerson(Person person) { // Open a StreamWriter to write to a JSON file using (var file = new StreamWriter("Person.json")) { // Use the JsonSerializer to serialize the person object to a JSON string var json = JsonSerializer.Serialize(person); // Write the JSON string to the file file.Write(json); // Write the JSON string to the console for debugging purposes Console.WriteLine(json); } } |
2.3 定義多個序列化功能
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private static void SerializePersonList(List<Person> personList) { // Open a StreamWriter to write to a JSON file using (var file = new StreamWriter("PersonList.json")) { // Use the JsonSerializer to serialize the list of person objects to a JSON string var json = JsonSerializer.Serialize(personList); // Write the JSON string to the file file.Write(json); // Write the JSON string to the console for debugging purposes Console.WriteLine(json); } } |
3.1 定義反序列化泛型類型
1 2 3 4 5 6 7 8 9 10 11 12 13 |
private static void DeserializePerson() { // Open a StreamReader to read from the JSON file using (var reader = new StreamReader("Person.json")) { // Read the entire contents of the file into a string var json = reader.ReadToEnd(); // Use the JsonSerializer to deserialize the JSON string into a Person object var deserializedPerson = JsonSerializer.Deserialize<Person>(json); // Write the deserialized person object to the console Console.WriteLine(deserializedPerson); } } |
3.2 定義單一反序列化功能
1 2 3 4 5 6 7 8 9 10 11 12 |
static function" >// DeserializeObject is a generic method that can deserialize a JSON string to an object of type T. private static T DeserializeObject<T>(string fileName) { // Use a StreamReader to read the JSON string from a file. using (var reader = new StreamReader(fileName)) { // Read the JSON string from the file. var json = reader.ReadToEnd(); // Use JsonSerializer to deserialize the JSON string to an object of type T. return JsonSerializer.Deserialize<T>(json); } } |
3.3 定義多個反序列化功能
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
private static void DeserializePersonList() { // Open a StreamReader to read from the JSON file using (var reader = new StreamReader("PersonList.json")) { // Read the entire contents of the file into a string var json = reader.ReadToEnd(); // Use the JsonSerializer to deserialize the JSON string into a list of Person objects var deserializedPersonList = JsonSerializer.Deserialize<List<Person>>(json); // Write each deserialized person object to the console foreach (var person in deserializedPersonList) { Console.WriteLine(person); } } } |
4. 測試程式代碼
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 |
static void Main(string[] args) { Console.WriteLine("One Person:"); //Create a new instance of Person var person = new Person { Name = "Jasson Chou", ID = 108 }; //Serialize the person object to "Person.json" file SerializeObject("Person.json", person); //Deserialize the "Person.json" file to a Person object var result = DeserializeObject<Person>("Person.json").ToString(); Console.WriteLine(result); Console.WriteLine("**************************************************"); Console.WriteLine("Multi-Person:"); //Create a list of person objects var personList = new List<Person> { new Person { Name = "Jasson Chou", ID = 108 }, new Person { Name = "Nico", ID = 109 }, new Person { Name = "Eric", ID = 120 }, }; //Serialize the list of person objects to "PersonList.json" file SerializeObject("PersonList.json", personList); //Deserialize the "PersonList.json" file to a List of Person objects var listresult = DeserializeObject<List<Person>>("PersonList.json").ToPrint(); Console.WriteLine(listresult); Console.WriteLine("**************************************************"); Console.ReadLine(); } |
5. 測試結果
下圖是測試Console畫面,顯示的是執行出來的結果,第一步份”One Person”序列化後返序列化出來的結果;第二部分”Multi-Person”也是一樣。
下方是Json Serializer出來的檔案內容,與代碼寫的一致。
結論
最後總結一下:
C#的JsonSerializer是一個非常方便的工具,可以將物件轉換成json格式的字串,或是將json字串反序列化成物件。這使得在存儲或交換資料時,能夠輕鬆地將物件序列化成可儲存或傳輸的格式,並且在需要使用時再將其反序列化回物件。
最後幫各位整理,學習C# Serializer Attribute需要注意的部分,如下:
- 理解序列化概念:首先,要理解序列化是將物件狀態轉換為可存儲或傳輸格式的過程,而反序列化則是將這些格式還原回物件。
- 掌握 Serializer 屬性的使用:學習如何使用 Serializer 屬性來標記類別和成員,以及如何通過這些屬性來定義序列化和反序列化的行為。
- 了解序列化過程的控制:深入了解如何利用這些屬性來控制哪些部分被序列化,如何處理敏感資料,以及如何應對特定序列化挑戰(例如循環引用)。
- 實踐和實驗:透過實際的編程練習來加強理解,包括實現自定義的序列化邏輯,並在不同的應用場景中進行實驗。
- 關注性能和安全性:學習如何在序列化過程中優化性能,以及如何確保資料的安全性,特別是在處理敏感資訊時。
- 持續學習和適應變化:隨著 C# 語言和 .NET 平台的發展,持續關注新的序列化功能和最佳實踐,並適應這些變化。
除了JsonSerializer以外,C#還有以下的Serializer用法:
- XMLSerializer
- BinaryFormatter
- SoapFormatter
- DataContractSerializer
- NetDataContractSerializer
- JavaScriptSerializer
- XmlSerializer
有興趣可以去看看。以上是我對Serializer的筆記。