接著上一節的內容,有時候我們在對象中,並不是所有的欄位需要序列化。
樣本:
以下是這個表單需要用到的實體類
using System;
using System.Collections.Generic;
using System.Text;
using System.Runtime.Serialization;
using System.Collections;
namespace MutliObjectSerialization2
{
[Serializable]
class CollegeStudent:IDeserializationCallback
{
public String Name="空";//姓名
public bool IsMale=true ; //性別
public int ScoreForEntranceExamination=0; //入學考試成績
public DateTime BirthDay=DateTime.Now; //生日
[NonSerialized]
public int Age=0; //年齡
void IDeserializationCallback.OnDeserialization(Object sender)
{
Age=DateTime.Now.Year-BirthDay.Year ;
}
}
[Serializable]
class StudentList//學生清單
{
public List<CollegeStudent> Students = new List<CollegeStudent>();//學生對象集合
}
}
我們仔細想想,會發現“年齡”欄位很特殊,它直接依賴於“生日”欄位的值,而且會隨著時間的推移而發生變化。如果在序列化時,將此欄位也序列化到檔案中,那麼無論什麼時候重建對象,“年齡”欄位的值都是不變的。這顯然不符合實際情況。
其實,只要知道了生日,拿當時日期一減,就可知道這個人的年齡,因此可以選擇不序列化“年齡”欄位,而在還原序列化對象時“現場”計算年齡再填入。這就需要對.net framework預設的對象序列化過程進行一定的調整。
在.net framework中,給類的一個欄位加上 [NonSerialized] 標記,即可讓此欄位不參與序列化。
.net framework還提供了一個 IDeserializationCallback 介面,它定義了一個 OnDeserialization 方法,可在還原序列化完成時自動調用這一方法。換名話說:如果讓 CollegeStudent類實現IDeserializationCallback介面(即提供一個OnDeserialization方法),則從流中重建CollegeStudent對象完成時,CLR會自動調用已定義好的OnDeserialization方法,可以在這個方法中寫代碼對年齡進行計算並填充“年齡”欄位。
本日記介紹了用[NonSerialized]標記和 IDeserializationCallback 介面來控制序列化過程。除此之外,framework還提供了以下4個代碼標記用於提供更多的控制手段。
[OnSerializedAttribute] : 在序列化完成後調用。
[OnSerializingAttribute] : 在序列化進行時調用。
[OnDeSerializedAttribute] :在還原序列化完成後調用。
[OnDeSerializingAttribute] : 在還原序列化進行時調用。
將這些標記附加到方法上(一個方法只能附加一個標記),則在合適的時機這些方法會被自動調用。