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

2022-05-08 12:24:10 字數 3027 閱讀 7746

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

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

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

零、開始序列化

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

[serializable]

public class myclass

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

引用兩個namespace:

using system.io;

using system.xml.serialization;

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

1code

2myclass cls 

=new

myclass();

3xmlserializer xmlserializer 

=new

xmlserializer(cls.gettype());

4memorystream stream 

=new

memorystream();

5xmlserializer.serialize(stream, cls);

6byte

buf 

=stream.toarray();

7string

xml 

=encoding.ascii.getstring(buf);

8stream.close();

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

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

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

一、第一次嘗試

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

1public

abstract

class

serializablebaseclass 2 

13} 

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

差異1:

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

差異2:

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

二、第二次嘗試

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

1public

object

deserialize(

string

xmlstring)

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

宣告:[serializable]

public class myclass : serializablebaseclass

使用:1

myclass cls 

=new

myclass();

2string

xml 

=cls. serialize();

3myclass cls1 

=(myclass)cls. deserialize(xml);

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

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

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

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

三、最後的嘗試

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

1[serializable()] 

2public

abstract

class

serializablebaseclass 

<

t>3 

1415

public

static

t deserialize(

string

xmlstring) 16 

23} 

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

[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.為什麼使用序列化 乙個原因...