c 中類的序列化 一般化解決方法及最後的疑問

2021-04-24 08:10:13 字數 2803 閱讀 6355

前一段時間因為頻繁使用類的序列化,所以一直在思考如何能更方便的使用這個功能,現在把一段時間的學習過程和大家分享,同時還有個疑問向大家請教,如果您已經非常熟悉類的序列化,那麼請您直接看第三部分。

什麼是類的序列化?說白了,就是把乙個類的例項轉化成一段xml格式或二進位制格式的資料,以便於網路傳輸、儲存等操作。

同理,反序列化就是把xml或者二進位制描述的物件還原成乙個類的例項。

零、開始序列化

在c#中,要實現類的序列化並不難,以xml序列化為例,首先我們宣告乙個類:

[serializable]

public class myclass

其中類宣告上面的一句[serializable]用來指示此類是可以序列化的,然後

引用兩個namespace:

using system.io;

using system.xml.serialization;

於是就可以執行下面**:

myclass cls = new myclass();

xmlserializer xmlserializer = new xmlserializer(cls.gettype());

memorystream stream = new memorystream();

xmlserializer.serialize(stream, cls);

byte buf = stream.toarray();

string xml = encoding.ascii.getstring(buf);

stream.close();

自此,序列化就完成了,xml序列儲存在string xml;變數中。

上述**不難理解,xmlserializer類用來提供xml序列化的功能,xmlserializer.serialize(stream, cls)方法,可以把類cls序列化,並將xml序列儲存在流stream中。

以上便是序列化的基本方法,可以滿足我們的需求。但問題是如果我們經常需要對數個類進行序列化和反序列化,就要頻繁的重複上述**,能不能讓類具備自己進行序列化的方法呢?

一、第一次嘗試

我首先想到,可以寫乙個基類,提供進行序列化的方法,任何想實現序列化的類,只需要繼承此類就可以具備此方法。於是構造抽象類:

public abstract class serializablebaseclass }

上面一段**和之前的**只有兩行不一樣:

差異1:

cls.gettype()變成gettype():其中gettype()是獲取當前例項的型別,在基類中呼叫gettype()得到的是當前例項的型別,而不是積累的型別。也就是說上述基類中呼叫gettype()不會得到」 serializablebaseclass」,更不會是」system.object」,而是當前物件例項的型別。

差異2:

cls變成this:同理,this引用是指向當前例項的,只不過在基類中,不能使用this直接訪問子類成員。當然通過型別轉換可以達到此目的,但不在本文討論範圍內。所以serialize(stream,this)會將整個物件序列化,而不會造成物件分割,只把基類給序列化了。

二、第二次嘗試

到此為止,任何類只要整合了serializablebaseclass就擁有了自我序列化的方法,但如何反序列化呢?我們在serializablebaseclass類中再新增乙個方法。

public object deserialize(string xmlstring)

此方法就實現了類的反序列化,我們可以這樣使用:

宣告:

[serializable]

public class myclass : serializablebaseclass

使用:

myclass cls = new myclass();

string xml = cls. serialize();

myclass cls1 = (myclass)cls. deserialize(xml);

這個使用乍一看沒什麼問題,但實際使用起來就很蹩腳

1、要想反序列化乙個類,先要建立這個類的例項,只為了呼叫deserialize()

2、呼叫deserialize()返回的是object型別,需要進行型別轉換

對於這兩個問題,我也考慮過很久,如果把deserialize()定義為static,那麼就不能使用gettype()方法,而其,也無法獲取子類的型別。

三、最後的嘗試

對於上述兩個問題,想了很久,始終沒想到解決辦法,直到一天和朋友討論c++stl的某個問題的時候,終於茅塞頓開,c#也是支援模板的呀,於是激動不已,改寫serializablebaseclass類:

[serializable()]

public abstract class serializablebaseclass

public static t deserialize(string xmlstring) }

這樣,問題就不完美的解決了(確實不完美)。為什麼不完美呢?那就看下面的**:

[serializable]

public class myclass : serializablebaseclass

使用:

myclass cls = myclass.deserialize(xmldata);

看似上述問題都解決了,但我還是心裡不爽,因為每次定義乙個繼承serializablebaseclass的類,還必須把自己的類名再寫一遍,放在模板型別的引數裡。有沒有一種方案,可以讓上述myclass類的宣告預設模板引數就是自身myclass,而無須再寫一遍 呢?或者還有更好的其他方法?歡迎討論

c 中類的序列化 一般化解決方法及最後的疑問

前一段時間因為頻繁使用類的序列化,所以一直在思考如何能更方便的使用這個功能,現在把一段時間的學習過程和大家分享,同時還有個疑問向大家請教,如果您已經非常熟悉類的序列化,那麼請您直接看第三部分。什麼是類的序列化?說白了,就是把乙個類的例項轉化成一段xml格式或二進位制格式的資料,以便於網路傳輸 儲存等...

C 中類的序列化和反序列化

說明 本文演示將類序列化後寫入記事本並從記事本讀取反序列化為物件 1.首先建立乙個類,同時類必須標識為serializable,如下 serializable public class region public string region id public string region name ...

C 中關於類的序列化

1.什麼是序列化 序列化是將物件狀態轉換為可保持或傳輸的格式的過程,在序列化過程中,物件的公共欄位和私有字段以及類的名稱 包括包含該類的程式集 都被轉換為位元組流,然後寫入資料流。與序列化相對的是反序列化,它將流轉換為物件。這兩個過程結合起來,可以輕鬆地儲存和傳輸資料。2.為什麼使用序列化 乙個原因...