要讓一個對象支持.Net序列化服務,用戶必須爲每個關聯的類加上[Serializable]特性。若是類中有些成員不適合參與序列化(好比:密碼字段),能夠在這些域前加上[NonSerialized]特性。html
C#支持三種序列化格式:二進制格式(使用BinaryFormatter序列化器)、SOAP格式(使用SoapFormatter序列化器)、XML格式(使用XmlSerializer序列化器)。這三種序列化器的區別以下:程序員
二進制格式可序列化一個類型的全部可序列化字段,無論它是公共字段仍是私有字段。SOAP格式和XML格式僅能序列化公共字段或擁有公共屬性的私有字段,未經過屬性公開的私有字段將被忽略。web
使用二進制格式序列化時,它不只是將對象的字段數據進行持久化,也持久化每一個類型的徹底限定名稱和定義程序集的完整名稱(包括包稱、版本、公鑰標記、區域性),這些數據使得在進行二進制格式反序列化時亦會進行類型檢查。SOAP格式序列化經過使用XML命名空間來持久化原始程序集信息。而XML格式序列化不會保存完整的類型名稱或程序集信息。這便利XML數據表現形式更有終端開放性。若是但願儘量延伸持久化對象圖的使用範圍時,SOAP格式和XML格式是理想選擇。編程
using
System;
using
System.Collections.Generic;
using
System.Text;
using
System.Runtime.Serialization.Formatters.Binary;
using
System.Runtime.Serialization.Formatters.Soap;
using
System.IO;
using
System.Xml.Serialization;
namespace
CollectionSerialize
{
class
Program
{
static
void
Main(
string
[] args)
{
//
文件名稱
string
fileName
=
"
Programmers.dat
"
;
//
建立Programmer列表,並添加對象
List
<
Programmer
>
list
=
new
List
<
Programmer
>
();
list.Add(
new
Programmer(
"
Coder1
"
,
false
,
"
C
"
));
list.Add(
new
Programmer(
"
Coder2
"
,
false
,
"
C++
"
));
list.Add(
new
Programmer(
"
Coder3
"
,
false
,
"
Java
"
));
//
建立文件流
Stream fStream
=
null
;
fStream
=
FileReset(fStream, fileName);
//
使用二進制序列化器
BinaryFormatter binFormat
=
new
BinaryFormatter();
//
將list序列化到文件中
binFormat.Serialize(fStream, list);
//
清空列表
list.Clear();
//
重置流位置
fStream.Position
=
0
;
//
反序列化,注意要將結果轉型
list
=
(List
<
Programmer
>
)binFormat.Deserialize(fStream);
//
輸出
Print(list);
fStream
=
FileReset(fStream, fileName);
//
使用XML序列化
//
注意使用此構造器時必須在第一個參數傳入序列化的類型,第二個參數傳入序列化所涉及的相關類型
XmlSerializer xmlFormat
=
new
XmlSerializer(
typeof
(List
<
Programmer
>
),
new
Type[] {
typeof
(Programmer),
typeof
(Person) });
//
反序列化
xmlFormat.Serialize(fStream, list);
list.Clear();
fStream.Position
=
0
;
//
反序列化,注意要將結果轉型
list
=
(List
<
Programmer
>
)xmlFormat.Deserialize(fStream);
Print(list);
fStream
=
FileReset(fStream, fileName);
//
使用SOAP序列化
SoapFormatter soapFormat
=
new
SoapFormatter();
//
序列化,Soap不能序列化泛型對象,因此只能指定序列化一個Programmer對象
soapFormat.Serialize(fStream, list[
0
]);
list.Clear();
fStream.Position
=
0
;
//
反序列化
list.Add((Programmer)soapFormat.Deserialize(fStream));
Print(list);
fStream.Close();
Console.ReadKey();
}
//
輸出程序員列表
static
void
Print(List
<
Programmer
>
list)
{
Console.WriteLine(
"
程序員信息列表:
"
);
foreach
(Programmer p
in
list)
{
Console.WriteLine(
"
姓名:{0} 性別:{1} 編程語言:{2}
"
,
p.Name, p.Sex.ToString(), p.Language);
}
}
//
重置文件
static
FileStream FileReset(Stream fStream,
string
fileName)
{
//
關閉文件流
if
(fStream
!=
null
)
{
fStream.Close();
}
//
刪除文件
File.Delete(fileName);
//
新建文件流
return
new
FileStream(fileName, FileMode.OpenOrCreate,
FileAccess.ReadWrite, FileShare.None);
}
}
[Serializable]
//
必須添加序列化特性
public
class
Person
{
//
姓名
public
string
Name;
//
性別
public
bool
Sex;
//
必須提供無參構造器,不然XmlSerializer將出錯
public
Person() { }
//
構造函數
public
Person(
string
name,
bool
sex)
{
this
.Name
=
name;
this
.Sex
=
sex;
}
}
[Serializable]
//
必須添加序列化特性
public
class
Programmer : Person
{
//
編程語言
public
string
Language;
//
必須提供無參構造器,不然XmlSerializer將出錯
public
Programmer() { }
//
構造函數
public
Programmer(
string
name,
bool
sex,
string
language)
:
base
(name, sex)
{
this
.Language
=
language;
}
}
}
1. SoapFormatter不能序列化泛型對象。
2. XmlSerializer的構造器須要傳入序列化涉及的相關類型信息。