如何理解.Net組件程序設(shè)計(jì)中的序列化,相信很多沒有經(jīng)驗(yàn)的人對此束手無策,為此本文總結(jié)了問題出現(xiàn)的原因和解決方法,通過這篇文章希望你能解決這個問題。
為云城等地區(qū)用戶提供了全套網(wǎng)頁設(shè)計(jì)制作服務(wù),及云城網(wǎng)站建設(shè)行業(yè)解決方案。主營業(yè)務(wù)為成都網(wǎng)站設(shè)計(jì)、成都做網(wǎng)站、云城網(wǎng)站設(shè)計(jì),以傳統(tǒng)方式定制建設(shè)網(wǎng)站,并提供域名空間備案等一條龍服務(wù),秉承以專業(yè)、用心的態(tài)度為用戶提供真誠的服務(wù)。我們深信只要達(dá)到每一位用戶的要求,就會得到認(rèn)可,從而選擇與我們長期合作。這樣,我們也可以走得更遠(yuǎn)!.Net組件程序設(shè)計(jì)之序列化
自動序列化
Serializable屬性
1 [Serializable] 2 public class SerializableCase 3 4 { 5 6 public SerializableCase() { } 7 8 private string _State; 9 10 public string State 11 12 { 13 14 get { return _State; } 15 16 set { _State = value; } 17 18 } 19 20 }
在上面的示例類型上加上Serializable屬性這樣將示例類型標(biāo)記為可序列化類型.
1 public class MySerializableCase 2 { 3 public static void BinaryFormatterSerialize() 4 { 5 IFormatter formatter = new BinaryFormatter(); 6 Stream stream = new FileStream("jin.glory", FileMode.Create, FileAccess.ReadWrite); 7 using (stream) 8 { 9 SerializableCase serCase = new SerializableCase(); 10 serCase.State = "Test"; 11 formatter.Serialize(stream, serCase); 12 } 13 } 14 15 public static void BinaryFormatterDesSerialize() 16 { 17 Stream stream = new FileStream("jin.glory", FileMode.Open, FileAccess.Read); 18 IFormatter formatter = new BinaryFormatter(); 19 using (stream) 20 { 21 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase; 22 return serCase.State; 23 } 24 } 25 }
BinaryFormattSerialize()方法里只是實(shí)例化SerializableCase類型,然后對State屬性賦值,代表一個狀態(tài)。調(diào)用 MySerializableCase.BinaryFormattSerialize()后.NET把序列化好的文件流保存到了jin.glory文件中.
圖1
文件的名稱和后綴格式都是自己隨便定義的。然后再調(diào)用反序列化,獲取到之前序列化的對象狀態(tài)。
1 string state = MySerializableCase.BinaryFormattDesSerialize(); 2 Console.WriteLine(state);
圖2
SoapFormatter是在命名空間System.Runtime.Serialization.Formatters.Soap下的(在System.Runtime.Serialization.Formatters.Soap.dll中)
1 public class MySerializableCase 2 { 3 public static void SoapFormatterSerialize() 4 { 5 IFormatter formatter = new SoapFormatter(); 6 Stream stream = new FileStream("Soap.xml", FileMode.Create, FileAccess.ReadWrite); 7 using (stream) 8 { 9 SerializableCase serCase = new SerializableCase(); 10 serCase.State = "Test"; 11 formatter.Serialize(stream, serCase); 12 } 13 } 14 15 public static string SoapFormatterDesSerialize() 16 { 17 Stream stream = new FileStream("Soap.xml", FileMode.Open, FileAccess.Read); 18 IFormatter formatter = new SoapFormatter(); 19 using (stream) 20 { 21 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase; 22 return serCase.State; 23 } 24 } 25 }
和上面的二進(jìn)制格式化器使用的方式近乎相同,唯一不同的是,使用Soap格式化器生成的序列化文件耗時更長,占用空間也比較大,但是它是遵循著SOAP協(xié)議的,這在跨平臺操作數(shù)據(jù)間是很有用的,平臺只需要解析重建就能把對象重新的生成出來。
1 [Serializable] 2 public class SerializableCase 3 { 4 public SerializableCase() { } 5 6 private string _State; 7 8 public string State 9 { 10 get { return _State; } 11 set { _State = value; } 12 } 13 14 [NonSerialized] 15 private DonotSerializable _DonotSerializable; 16 17 public DonotSerializable DonotSerializable 18 { 19 get { return _DonotSerializable; } 20 set { _DonotSerializable = value; } 21 } 22 } 23 public class DonotSerializable 24 { 25 public DonotSerializable() { } 26 27 public string DonotSerializableData 28 { 29 get; 30 set; 31 } 32 }
修改了一下第一段的示例代碼,增加了個屬性,并且設(shè)置其字段為NonSerialized,這樣在.NET序列化這個類的實(shí)例的時候,檢測到了[NonSerialized]的時候就會跳過它,因?yàn)橛械膶ο蟠_實(shí)是不適合序列化來進(jìn)行持久化的,不過這樣的做的也會有個問題,就是對象的狀態(tài)丟失,就是不可序列化的部分會丟失??匆幌孪旅娴拇a:
1 public class MySerializableCase 2 { 3 public static void BinaryFormatterSerialize() 4 { 5 IFormatter formatter = new BinaryFormatter(); 6 Stream stream = new FileStream("jin.glory", FileMode.Create, FileAccess.ReadWrite); 7 using (stream) 8 { 9 SerializableCase serCase = new SerializableCase(); 10 serCase.State = "Test"; 11 serCase.DonotSerializable = new DonotSerializable(); 12 serCase.DonotSerializable.DonotSerializableData = "DonotSerializableData"; 13 formatter.Serialize(stream, serCase); 14 } 15 } 16 17 public static string BinaryFormatterDesSerialize() 18 { 19 Stream stream = new FileStream("jin.glory", FileMode.Open, FileAccess.Read); 20 IFormatter formatter = new BinaryFormatter(); 21 using (stream) 22 { 23 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase; 24 return serCase.State+"_"+serCase.DonotSerializable.DonotSerializableData; 25 } 26 } 27 }
修改了上面的二進(jìn)制格式器的代碼,調(diào)用一下測試代碼我們一起來看下結(jié)果:
1 MySerializableCase.BinaryFormatterSerialize(); 2 string state = MySerializableCase.BinaryFormatterDesSerialize(); 3 Console.WriteLine(state);
圖3
在反序列化的時候,對象SerializableCase的DonotSerializable屬性丟失了,所以才會報(bào)錯。
對于這樣的情況,.NET提供了IDeserializationCallback接口,它里面只有一個函數(shù)void OnDeserialization(object sender),只要實(shí)現(xiàn)了IDeserializationCallback,并且在OnDeserialization函數(shù)里實(shí)現(xiàn)具體的對不可序列化對象的初始化。
1 [Serializable] 2 public class SerializableCase:IDeserializationCallback 3 { 4 public SerializableCase() { } 5 6 private string _State; 7 8 public string State 9 { 10 get { return _State; } 11 set { _State = value; } 12 } 13 14 [NonSerialized] 15 private DonotSerializable _DonotSerializable; 16 17 public DonotSerializable DonotSerializable 18 { 19 get { return _DonotSerializable; } 20 set { _DonotSerializable = value; } 21 } 22 23 public void OnDeserialization(object sender) 24 { 25 _DonotSerializable = new DonotSerializable(); 26 _DonotSerializable.DonotSerializableData = "DonotSerializableData->Test"; 27 } 28 }
按照上面的調(diào)用方式,來看一下結(jié)果:
圖4
這樣是在反序列化的時候,如果檢測到了實(shí)例類型實(shí)現(xiàn)了IDeserializationCallback接口,是在反序列化完成的時候會執(zhí)行實(shí)現(xiàn)了IDeserializationCallback的OnDeserialization()方法,這樣可以對一些不可序列化的屬性狀態(tài)在這個方法里來實(shí)現(xiàn)。
.NET2.0
引進(jìn)了對序列化事件的支持,當(dāng)序列化和反序列化的時候,.NET在你的類上調(diào)用指定的方法,.NET中定義了四個序列化和反序列化事件。
serializing事件是在序列化發(fā)生之前被觸發(fā),
serialized 事件是在序列化之后被觸發(fā),
deserializing事件是在反序列化之前被觸發(fā),
deserialized事件是在反序列化之后被觸發(fā)。
引用先前的示例代碼SerializableCase類的初始代碼:
[Serializable] public class SerializableCase //:IDeserializationCallback { public SerializableCase() { } private string _State; public string State { get { return _State; } set { _State = value; } } }
添加了事件后的示例代碼是這樣的:
1 [Serializable] 2 public class SerializableCase 3 { 4 public SerializableCase() { } 5 private string _State; 6 public string State 7 { 8 get { return _State; } 9 set { _State = value; } 10 } 11 12 [OnSerializing] 13 private void OnSerializing(StreamingContext context) 14 { 15 _State = "此時的狀態(tài)是:序列化之前"; 16 Console.WriteLine(State); 17 } 18 19 [OnSerialized] 20 private void OnSerialized(StreamingContext context) 21 { 22 _State = "此時的狀態(tài)是:序列化之后"; 23 Console.WriteLine(State); 24 } 25 26 [OnDeserializing] 27 private void OnDeserializing(StreamingContext context) 28 { 29 _State = "此時的狀態(tài)是:反序列化之前"; 30 Console.WriteLine(State); 31 } 32 33 [OnDeserialized] 34 private void OnDeserialized(StreamingContext context) 35 { 36 _State = "此時的狀態(tài)是:反序列化之后"; 37 Console.WriteLine(State); 38 } 39 }
使用之前定義好的MySerializableCase類型中的靜態(tài)方法,稍作修改來演示一下,
1 public static void SoapFormatterSerialize() 2 { 3 IFormatter formatter = new SoapFormatter(); 4 Stream stream = new FileStream("Soap.xml", FileMode.Create, FileAccess.ReadWrite); 5 using (stream) 6 { 7 SerializableCase serCase = new SerializableCase(); 8 formatter.Serialize(stream, serCase); 9 } 10 } 11 public static string SoapFormatterDesSerialize() 12 { 13 Stream stream = new FileStream("Soap.xml", FileMode.Open, FileAccess.Read); 14 IFormatter formatter = new SoapFormatter(); 15 using (stream) 16 { 17 SerializableCase serCase = formatter.Deserialize(stream) as SerializableCase; 18 return serCase.State; 19 } 20 21 }
測試代碼:
1 MySerializableCase.SoapFormatterSerialize(); 2 MySerializableCase.SoapFormatterDesSerialize(); 3 Console.ReadLine();
圖5
從結(jié)果中就很明顯的顯示出來了,這里要說幾句題外話,細(xì)心的朋友可能發(fā)現(xiàn)了,在SerializableCase類型中的四個事件函數(shù)簽名都是相同的,這是因?yàn)樵?NET中為這個這個序列化和反序列化事件定義的委托就是這個簽名,在這個類型實(shí)例序列化和反序列化的時候會檢測到.NET會反射實(shí)例內(nèi)部所有的函數(shù) 檢測是否有附加了序列化事件,如果判斷了有則會繼續(xù)檢查這個函數(shù)的簽名,如果函數(shù)簽名也匹配了,就會把這個函數(shù)掛上委托。
可以這樣指定一個函數(shù)為事件指定調(diào)用函數(shù):
1 [OnSerializing] 2 [OnSerialized] 3 [OnDeserializing] 4 [OnDeserialized] 5 private void OnGenericSerializEventMethod(StreamingContext context) 6 { 7 …… 8 }
看完上述內(nèi)容,你們掌握如何理解.Net組件程序設(shè)計(jì)中的序列化的方法了嗎?如果還想學(xué)到更多技能或想了解更多相關(guān)內(nèi)容,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道,感謝各位的閱讀!
創(chuàng)新互聯(lián)www.cdcxhl.cn,專業(yè)提供香港、美國云服務(wù)器,動態(tài)BGP最優(yōu)骨干路由自動選擇,持續(xù)穩(wěn)定高效的網(wǎng)絡(luò)助力業(yè)務(wù)部署。公司持有工信部辦法的idc、isp許可證, 機(jī)房獨(dú)有T級流量清洗系統(tǒng)配攻擊溯源,準(zhǔn)確進(jìn)行流量調(diào)度,確保服務(wù)器高可用性。佳節(jié)活動現(xiàn)已開啟,新人活動云服務(wù)器買多久送多久。
標(biāo)題名稱:如何理解.Net組件程序設(shè)計(jì)中的序列化-創(chuàng)新互聯(lián)
文章轉(zhuǎn)載:http://muchs.cn/article26/pgscg.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供全網(wǎng)營銷推廣、面包屑導(dǎo)航、動態(tài)網(wǎng)站、企業(yè)建站、微信公眾號、網(wǎng)站制作
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點(diǎn)不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)