C#對象序列化(2)

來源:互聯網
上載者:User
C#對象序列化(2)作者: 日期:2009-3-14 23:42:29 出處:淘特網

解析

對象序列化可以使對象的資料持久地儲存,對象狀態可以是Ssytem.IO.Stream的衍生類別型。並不是任何類型的對象都可以被序列化的,只有當其類型定義為可序列化時,該對象才可以被序列化。例如,自訂一個類類型,當該類類型被標記了[Serializable]特性後,其對象即可被序列化。序列化的代碼本身很簡單,並可使用多種格式儲存對象(或對象圖),如二進位格式、SOAP格式和XML格式。

將對象以二進位格式序列化,需要使用BinaryFormatter類型,該類型位於mscorlib.dll程式集,使用時只需匯入其命名空間即可,程式碼如以下代碼所示:

//匯入BinaryFormatter類的命名空間
using System.Runtime.Serialization.Formatters.Binary;
//建立BinaryFormatter類對象MyBF
BinaryFormatter MyBF = new BinaryFormatter();
//建立自訂類MyClass的對象引用obj,該類已經標記了[Serializable]特性
MyClass obj = new MyClass();
//建立Stream類型引用fs
Stream fs = new FileStream(需要儲存的路徑, FileMode.Create,
FileAccess.Write, FileShare.None);
//調用MyBF的Serialize方法,傳遞fs和obj參數
MyBF.Serialize(fs, Pn);
//關閉fs對象
fs.Close();

可見,只需調用BinaryFormatter類對象的Serialize()方法,即可完成序列化的操作。如果使用SOAP格式序列化,其操作和二進位格式基本一致,只是由SoapFormatter類的對象調用Serialize()方法。由於定義SoapFormatter類的命名空間是 System.Runtime. Serialization.Formatters.Soap,而這個命名空間定義於System.Runtime.Serialization. Formatters.Soap.dll程式集內,所以使用SoapFormatter類時,需手動引用該程式集,然後匯入該命名空間。實際上,BinaryFormatter類和SoapFormatter類都實現了IFormatter介面,所以在程式應用中,可以編寫相應的多態程式。

XML格式序列化對象需要建立System.Xml.Serialization.XmlSerializer類對象,然後調用 Serialize()方法。該類的命名空間雖然定義於System.Xml.dll程式集內,但是Visual Studio 2005/ Visual Studio 2008將自動引用該程式集,所以不需要手動引用System.Xml.dll程式集。XML格式序列化的方法如以下代碼所示:

//匯入XmlSerializer類的命名空間
using System.Xml.Serialization;
//建立XmlSerializer類對象MyXS
XmlSerializer MyXS = new XmlSerializer(typeof(MyClass),
要序列化其他對象的Type類型數組);
//建立自訂類MyClass的對象引用obj,該類已經標記了[Serializable]特性
MyClass obj = new MyClass();
//建立Stream類型引用fs
Stream fs = new FileStream(需要儲存的路徑, FileMode.Create,
FileAccess.Write, FileShare.None);
//調用MyXS的Serialize方法,傳遞fs和obj參數
MyXS.Serialize(fs, Pn);
//關閉fs對象
fs.Close();

XmlSerializer類的建構函式需要傳遞參數,當只需要實現一個獨立對象時,傳遞該對象所屬類的Type物件類型即可,當該對象依賴於其他對象時,需要將其他對象所屬類的Type物件類型作為數組傳遞。

說明:對象圖是指一組關聯的對象關係圖,描述了多個對象之間的依賴關係。

面試例題21:如何將XML格式持久化的對象還原序列化?

考點:還原序列化的基本方法,處理還原序列化後的對象資料。

出現頻率:★★

解答

在Visual Studio 2005/ Visual Studio 2008中建立一個C#的Windows表單應用程式項目,並將其項目命名為ListSerialize。程式序列化的對象是List<T> 類的對象(該類是可序列化的),通過"添加"按鈕控制項,增加List<T>類對象中的子項,直到單擊"輸出XML"按鈕。而單擊"XML還原序列化"按鈕後,指定XML檔案中的對象資訊還原,並在ListBox控制項(命名為"XmlList")中輸出該對象的每個子項資料。在Visual Studio 2005/ Visual Studio 2008的"Form1.cs[設計]"視圖中建立基本的表單布局和控制項,控制項的命名7.50所示。

(點擊查看大圖)圖7.50 還原序列化程表單控制項布局及命名

編寫ListSerialize項目的Form1.cs如代碼7.26所示。

代碼7.26 還原序列化對象:Form1.cs

using System;
………………………………………
//匯入必要的命名空間
using System.Xml.Serialization;
using System.Runtime.Serialization;
using System.IO;

 

namespace ListSerialize
{
public partial class Form1 : Form
{
//建立List<T>類型對象list,子項類型為PersonDetail
List<PersonDetail> list = new List<PersonDetail>();
//聲明List<T>類型readlist變數,子項類型為PersonDetail
List<PersonDetail> readlist;
//聲明fn變數,用於隱藏檔路徑
string fn;
public Form1()
{
InitializeComponent();
}

 

private void AddBtn_Click(object sender, EventArgs e)
{
//建立PersonDetail類型對象Pd
PersonDetail Pd = new PersonDetail();
//將兩個文字框控制項內容賦值給Pd的兩個對象
Pd.Name = nametxt.Text;
Pd.Password = passwordtxt.Text;
//list對象添加子項Pd
list.Add(Pd);
MessageBox.Show("添加成功");
}

 

private void OutputBtn_Click(object sender, EventArgs e)
{
//擷取使用者輸入的檔案路徑
fn = FileName.Text;
//建立XmlSerializer的對象引用Xs,並傳遞List<PersonDetail>的類型
XmlSerializer Xs = new XmlSerializer(typeof(List<PersonDetail>));
//建立Stream類型引用fs,並傳遞fn作路徑參數
Stream fs = new FileStream(fn, FileMode.Create, FileAccess.Write, FileShare.None);
//調用Xs的Serialize方法,傳遞fs和list參數
Xs.Serialize(fs, list);
//關閉fs對象
fs.Close();
MessageBox.Show("XML序列化成功");
//將文字框控制項清空
nametxt.Text = "";
passwordtxt.Text = "";
FileName.Text = "";
}

 

private void InputBtn_Click(object sender, EventArgs e)
{
string str;
//擷取使用者輸入的檔案路徑
fn = ReadFileName.Text;
try
{
//建立FileStream類型引用fs,並傳遞fn作路徑參數,檔案模式為開啟檔案
FileStream fs = new FileStream(fn, FileMode.Open);
//建立XmlSerializer類型對象Xs,傳遞List<PersonDetail>的類型
XmlSerializer Xs = new XmlSerializer(typeof(List<PersonDetail>));
//調用Xs的Deserialize方法,傳遞fs
//將返回的對象轉換為List<PersonDetail>類型,並將引用賦值給readlist
readlist = (List<PersonDetail>)Xs.Deserialize(fs);
//遍曆readlist的每個子項
foreach (PersonDetail Pd in readlist)
{
//將子項的屬性值組合後賦值給str變數
str = String.Format("姓名:【{0}】,密碼:【{1}】", Pd.Name, Pd.Password);
//調用XmlList控制項Items的Add方法,將str添加為項
XmlList.Items.Add(str);
}
}
//處理檔案未找到異常
catch (FileNotFoundException ex)
{
string msg = String.Format("異常資訊:{0}", ex.Message);
MessageBox.Show(msg);
}
//將檔案路徑文字框控制項清空
ReadFileName.Text = "";
}
}

 

public class PersonDetail
{
//定義兩個私人欄位
string _name;
string _password;
//定義兩個公用屬性,可以讀寫相應的私人欄位
public string Name
{
get
{
return _name;
}
set
{
_name = value;
}
}
public string Password
{
get
{
return _password;
}
set
{
_password = value;
}
}
public PersonDetail() { }
}
}

程式運行後,在前兩個"TextBox"控制項中輸入一組值並單擊"添加"按鈕,結果7.51所示。

使用者每單擊一次"添加"按鈕,list對象中將添加一個子項,該子項是根據使用者輸入值初始化的PersonDetail類的對象。當子項添加操作完成後,程式彈出7.51所示的資訊對話方塊。進行多次添加操作後,在Name屬性為"ReadFileName"的文字框控制項輸入任意XML檔案的檔案名稱,單擊"輸出XML"按鈕,即可完成XML格式的序列化操作。可將序列化操作建立的XML檔案名稱再次輸入到Name屬性為ReadFileName的文字框控制項中,然後單擊"XML還原序列化"按鈕即可完成該XML檔案中資料的還原序列化操作,運行結果7.52所示。

圖7.51 以XML格式序列化
(點擊查看大圖)圖7.52 還原序列化XML檔案並輸出

根據輸入值,建立的list對象資料已經被成功還原序列化,並且在Name屬性為"XmlList"的列表框控制項中顯示。

解析

還原序列化是序列化的逆向操作,既然序列化操作需要寫入到流,還原序列化即讀取流並將對象資料提取出來。例如,在程式集相同目錄下有一個"Person.dat"檔案,該檔案以二進位格式持久化已知類型(如PersonName類)的對象,其還原序列化的方法如以下代碼所示:

//匯入BinaryFormatter類的命名空間
using System.Runtime.Serialization.Formatters.Binary;
//建立BinaryFormatter類對象MyBF
BinaryFormatter MyBF = new BinaryFormatter();
//建立FileStream 類型引用fs,讀取"Person.dat"檔案
FileStream fs = new FileStream("Person.dat", FileMode.Open);
//調用MyBF的DeSerialize方法,傳遞fs參數
PersonName Pn = (PersonName)MyBF.DeSerialize(fs);
//關閉fs對象
fs.Close();

以上代碼中,程式獲得了PersonName類對象的引用Pn,該對象根據"Person.dat"檔案還原序列化建立,還原原對象的資料。

面試例題22:如何自訂序列化?

考點:理解自訂序列化,學習自訂序列化方法。

出現頻率:★★★★

解答

在Visual Studio 2005/ Visual Studio 2008中建立一個C#的Windows表單應用程式項目,並將其項目命名為CustomSerialize。程式可以根據使用者輸入值建立一個對象,以二進位格式序列化對象,並持久化到指定的路徑。這個過程,對象的欄位值將被添加一段字串,並且其欄位值對應的鍵名也被修改為指定值,而不是欄位名稱。在還原序列化的過程中,對象的欄位資料值被修改為原始值,所以看上去對象資料沒有作任何修改。在Visual Studio 2005/Visual Studio 2008的"Form1.cs[設計]"視圖中建立基本的表單布局和控制項,控制項的命名7.53所示。

(點擊查看大圖)圖7.53 自訂序列化表單控制項布局及命名

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.