c#對(duì)象反序列化與對(duì)象序列化示例詳解
1.對(duì)象序列化的介紹
(1).NET支持對(duì)象序列化的幾種方式
二進(jìn)制序列化:對(duì)象序列化之后是二進(jìn)制形式的,通過(guò)BinaryFormatter類來(lái)實(shí)現(xiàn)的,這個(gè)類位于System.Runtime.Serialization.Formatters.Binary命名空間下。
SOAP序列化:對(duì)象序列化之后的結(jié)果符合SOAP協(xié)議,也就是可以通過(guò)SOAP 協(xié)議傳輸,通過(guò)System.Runtime.Serialization.Formatters.Soap命名空間下的SoapFormatter類來(lái)實(shí)現(xiàn)的。
XML序列化:對(duì)象序列化之后的結(jié)果是XML形式的,通過(guò)XmlSerializer 類來(lái)實(shí)現(xiàn)的,這個(gè)類位于System.Xml.Serialization命名空間下。XML序列化不能序列化私有數(shù)據(jù)。
(2)幾種序列化的區(qū)別
二進(jìn)制格式和SOAP格式可序列化一個(gè)類型的所有可序列化字段,不管它是公共字段還是私有字段。XML格式僅能序列化公共字段或擁有公共屬性的私有字段,未通過(guò)屬性公開(kāi)的私有字段將被忽略。
使用二進(jìn)制格式序列化時(shí),它不僅是將對(duì)象的字段數(shù)據(jù)進(jìn)行持久化,也持久化每個(gè)類型的完全限定名稱和定義程序集的完整名稱(包括包稱、版本、公鑰標(biāo)記、區(qū)域性),這些數(shù)據(jù)使得在進(jìn)行二進(jìn)制格式反序列化時(shí)亦會(huì)進(jìn)行類型檢查。SOAP格式序列化通過(guò)使用XML命名空間來(lái)持久化原始程序集信息。而XML格式序列化不會(huì)保存完整的類型名稱或程序集信息。這便利XML數(shù)據(jù)表現(xiàn)形式更有終端開(kāi)放性。如果希望盡可能延伸持久化對(duì)象圖的使用范圍時(shí),SOAP格式和XML格式是理想選擇。
(3)使用特性對(duì)序列化的控制
要讓一個(gè)對(duì)象支持.Net序列化服務(wù),用戶必須為每一個(gè)關(guān)聯(lián)的類加上[Serializable]特性。如果類中有些成員不適合參與序列化(比如:密碼字段),可以在這些域前加上[NonSerialized]特性。
2.使用二進(jìn)制序列化和反序列化
(1)二進(jìn)制序列化與反序列化的程序示例
[Serializable] //必須添加序列化特性
public class Person
{
private string Name;//姓名
private bool Sex;//性別,是否是男
public Person(string name, bool sex)
{
this.Name = name;
this.Sex = sex;
}
public override string ToString()
{
return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");
}
}
[Serializable] //必須添加序列化特性
public class Programmer : Person
{
private string Language;//編程語(yǔ)言
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程語(yǔ)言:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//創(chuàng)建Programmer列表,并添加對(duì)象
List<Programmer> list = new List<Programmer>();
list.Add(new Programmer("李志偉", true, "C#"));
list.Add(new Programmer("Coder2", false, "C++"));
list.Add(new Programmer("Coder3", true, "Java"));
//使用二進(jìn)制序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.dat";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
BinaryFormatter binFormat = new BinaryFormatter();//創(chuàng)建二進(jìn)制序列化器
binFormat.Serialize(fStream, list);
//使用二進(jìn)制反序列化對(duì)象
list.Clear();//清空列表
fStream.Position = 0;//重置流位置
list = (List<Programmer>)binFormat.Deserialize(fStream);//反序列化對(duì)象
foreach (Programmer p in list)
{
Console.WriteLine(p);
}
Console.Read();
}
}
(2)總結(jié)
使用二進(jìn)制序列化,必須為每一個(gè)要序列化的的類和其關(guān)聯(lián)的類加上[Serializable]特性,對(duì)類中不需要序列化的成員可以使用[NonSerialized]特性。
二進(jìn)制序列化對(duì)象時(shí),能序列化類的所有成員(包括私有的),且不需要類有無(wú)參數(shù)的構(gòu)造方法。
使用二進(jìn)制格式序列化時(shí),它不僅是將對(duì)象的字段數(shù)據(jù)進(jìn)行持久化,也持久化每個(gè)類型的完全限定名稱和定義程序集的完整名稱(包括包稱、版本、公鑰標(biāo)記、區(qū)域性),這些數(shù)據(jù)使得在進(jìn)行二進(jìn)制格式反序列化時(shí)亦會(huì)進(jìn)行類型檢查。所以反序列化時(shí)的運(yùn)行環(huán)境要與序列化時(shí)的運(yùn)行環(huán)境要相同,否者可能會(huì)無(wú)法反序列化成功。
3.使用SOAP方式序列化和反序列化
(1)SOAP序列化與反序列化的程序示例
[Serializable] //必須添加序列化特性
public class Person
{
private string Name;//姓名
private bool Sex;//性別,是否是男
public Person(string name, bool sex)
{
this.Name = name;
this.Sex = sex;
}
public override string ToString()
{
return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");
}
}
[Serializable] //必須添加序列化特性
public class Programmer : Person
{
private string Language;//編程語(yǔ)言
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程語(yǔ)言:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//實(shí)例化對(duì)象
Programmer p = new Programmer("李志偉", true, "C、C#、C++、Java");
//使用SOAP序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
SoapFormatter soapFormat = new SoapFormatter();//創(chuàng)建SOAP序列化器
soapFormat.Serialize(fStream, p);//SOAP不能序列化泛型對(duì)象
//使用SOAP反序列化對(duì)象
fStream.Position = 0;//重置流位置
p = null;
p = (Programmer)soapFormat.Deserialize(fStream);
Console.WriteLine(p);
Console.Read();
}
}
(2)總結(jié)
SOAP序列化與二進(jìn)制序列化的區(qū)別是:SOAP序列化不能序列化泛型類型。與二進(jìn)制序列化一樣在序列化時(shí)不需要向序列化器指定序列化對(duì)象的類型。而XML序列化需要向XML序列化器指定序列化對(duì)象的類型。
4.使用XML方式序列化和反序列化
(1)XML序列化與反序列化的程序示例
public class Person
{
public string Name;//姓名
public bool Sex;//性別,是否是男
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
public Person(string name, bool sex)
{
this.Name = name;
this.Sex = sex;
}
public override string ToString()
{
return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");
}
}
public class Programmer : Person
{
public string Language;//編程語(yǔ)言
public Programmer() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程語(yǔ)言:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//創(chuàng)建Programmer列表,并添加對(duì)象
List<Programmer> list = new List<Programmer>();
list.Add(new Programmer("李志偉", true, "C#"));
list.Add(new Programmer("Coder2", false, "C++"));
list.Add(new Programmer("Coder3", true, "Java"));
//使用XML序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
XmlSerializer xmlFormat = new XmlSerializer(
typeof(List<Programmer>),
new Type[] { typeof(Programmer),typeof(Person) }
);//創(chuàng)建XML序列化器,需要指定對(duì)象的類型
xmlFormat.Serialize(fStream, list);
//使用XML反序列化對(duì)象
fStream.Position = 0;//重置流位置
list.Clear();
list = (List<Programmer>)xmlFormat.Deserialize(fStream);
foreach (Programmer p in list)
{
Console.WriteLine(p);
}
Console.Read();
}
}
(2)總結(jié)
使用XML序列化或反序列化時(shí),需要對(duì)XML序列化器指定需要序列化對(duì)象的類型和其關(guān)聯(lián)的類型。
XML序列化只能序列化對(duì)象的公有屬性,并且要求對(duì)象有一個(gè)無(wú)參的構(gòu)造方法,否者無(wú)法反序列化。
[Serializable]和[NonSerialized]特性對(duì)XML序列化無(wú)效!所以使用XML序列化時(shí)不需要對(duì)對(duì)象增加[Serializable]特性。
5.XML序列化對(duì)象詳解
(1)說(shuō)明
本節(jié)主要介紹:使用特性控制對(duì)象序列化成XML文件的格式。
(2)使用XmlElement(默認(rèn)值)
類聲明:
public class Person
{
[XmlElement]
public string Name;//使用[XmlElement]特性
public bool Sex;//默認(rèn)使用了[XmlElement]特性
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="...">
<Name>李志偉</Name>
<Sex>true</Sex>
</Person>
(3)使用XmlAttribute
類聲明:
public class Person
{
[XmlElement]
public string Name;
[XmlAttribute]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">
<Name>李志偉</Name>
</Person>
(4)使用XmlText
類聲明:
public class Person
{
[XmlText]
public string Name;
[XmlAttribute]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">李志偉</Person>
(5)使用XmlType和XmlAttribute(重命名節(jié)點(diǎn)名稱)
類聲明:
[XmlType("個(gè)人信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
序列化生成的XML文件:
<個(gè)人信息xmlns:xsi="..."xmlns:xsd="..."姓名="李志偉"性別="true" />
(6)列表和數(shù)組的序列化
類聲明:
[XmlType("個(gè)人信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "李志偉";
p.Sex = true;
Person[] ps = new Person[3];
ps[0] = p;
ps[1] = p;
ps[2] = p;
//使用XML序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(Person[]));
xmlFormat.Serialize(fStream, ps);//序列化對(duì)象
fStream.Dispose();//關(guān)閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<ArrayOf個(gè)人信息xmlns:xsi="..."xmlns:xsd="...">
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
</ArrayOf個(gè)人信息>
注意:發(fā)現(xiàn)此時(shí)的XML文件的根節(jié)點(diǎn)名稱變了。此時(shí)要重命名根節(jié)點(diǎn)應(yīng)使用如下方式:
[XmlType("個(gè)人信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
[XmlType("人員信息")]
public class PersonArray : List<Person> { }
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "李志偉";
p.Sex = true;
PersonArray ps = new PersonArray();
ps.Add(p);
ps.Add(p);
ps.Add(p);
//使用XML序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對(duì)象
fStream.Dispose();//關(guān)閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<人員信息xmlns:xsi="..."xmlns:xsd="...">
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
</人員信息>
(7)列表和數(shù)組的做為數(shù)據(jù)成員的序列化
類聲明:
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
public class PersonArray
{
public List<Person> Array=new List<Person>();
public Person Person = new Person();
}
class Program
{
static void Main(string[] args)
{
PersonArray ps = new PersonArray();
ps.Person = new Person();
ps.Person.Name = "李志偉";
ps.Person.Sex = true;
ps.Array.Add(ps.Person);
ps.Array.Add(ps.Person);
ps.Array.Add(ps.Person);
//使用XML序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對(duì)象
fStream.Dispose();//關(guān)閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<Array>
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
</Array>
<Person姓名="李志偉"性別="true" />
</PersonArray>
注意:假設(shè)這里需要為Array和Person的節(jié)點(diǎn)重命名,代碼如下:
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
public class PersonArray
{
[XmlArrayItem("個(gè)人信息")]
[XmlArray("人員信息")]
public List<Person> Array=new List<Person>();
public Person Person = new Person();
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<人員信息>
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
</人員信息>
<Person姓名="李志偉"性別="true" />
</PersonArray>
注意:把“人員信息”節(jié)點(diǎn)去掉呢(直接出現(xiàn)“個(gè)人信息”節(jié)點(diǎn))
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
public class PersonArray
{
[XmlElement("個(gè)人信息")]
public List<Person> Array=new List<Person>();
public Person Person = new Person();
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<個(gè)人信息姓名="李志偉"性別="true" />
<Person姓名="李志偉"性別="true" />
</PersonArray>
(8)類型繼承與反序列化
類聲明:
public class Base { }
[XmlType("信息A")]
public class PersonA : Base
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public PersonA() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
[XmlType("信息B")]
public class PersonB : Base
{
[XmlElement("姓名")]
public string Name;
[XmlElement("年齡")]
public int Age;
public PersonB() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
[XmlType("人員信息")]
public class PersonArray
{
[XmlArrayItem(typeof(PersonA)), XmlArrayItem(typeof(PersonB))]
public List<Base> ListPerson=new List<Base>();
}
class Program
{
static void Main(string[] args)
{
PersonA pa = new PersonA();
pa.Name = "李志偉A";
pa.Sex = true;
PersonB pb = new PersonB();
pb.Name = "李志偉B";
pb.Age = 21;
PersonArray ps = new PersonArray();
ps.ListPerson.Add(pa);
ps.ListPerson.Add(pa);
ps.ListPerson.Add(pb);
ps.ListPerson.Add(pb);
//使用XML序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對(duì)象
fStream.Dispose();//關(guān)閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<人員信息xmlns:xsi="..."xmlns:xsd="...">
<ListPerson>
<信息A姓名="李志偉A"性別="true" />
<信息A姓名="李志偉A"性別="true" />
<信息B>
<姓名>李志偉B</姓名>
<年齡>21</年齡>
</信息B>
<信息B>
<姓名>李志偉B</姓名>
<年齡>21</年齡>
</信息B>
</ListPerson>
</人員信息>
注意:同時(shí)為列表成員指定多個(gè)[XmlArrayItem(typeof(XXX))]可實(shí)現(xiàn)多種派生類型混在一起輸出。
(9)排除不需要序列化的成員
類聲明:
public class Person
{
public string Name;
[XmlIgnore]// 這個(gè)屬性將不會(huì)參與序列化
public bool Sex;
public Person() { }
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="...">
<Name>李志偉</Name>
</Person>
(10)強(qiáng)制指定成員的序列化順序
類聲明:
public class Person
{
[XmlElement(Order = 2)]
public string Name;
[XmlElement(Order = 1)]
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="...">
<Sex>true</Sex>
<Name>李志偉</Name>
</Person>
(11)自定義序列化行為
類聲明:
public class Person : IXmlSerializable
{
public string Name;
public bool Sex;
public Person() { }//必須提供無(wú)參構(gòu)造器,否則XmlSerializer將出錯(cuò)
public System.Xml.Schema.XmlSchema GetSchema()
{
return null;
}
public void ReadXml(System.Xml.XmlReader reader)
{
Name = reader.GetAttribute("姓名");
Sex = reader.GetAttribute("性別").Equals("男") ? true : false;
}
public void WriteXml(System.Xml.XmlWriter writer)
{
writer.WriteAttributeString("姓名", Name);
writer.WriteAttributeString("性別", Sex ? "男" : "女");
}
}
序列化生成的XML文件:
<Person姓名="李志偉"性別="男" />
(12)序列化設(shè)置XML命名空間
類聲明:
[XmlRoot(Namespace = "http://msdn.microsoft.com/vsdh.xsd")]
public class Person
{
public string Name;
public bool Sex;
public Person() { }
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="..."xmlns="http://msdn.microsoft.com/vsdh.xsd">
<Name>李志偉A</Name>
<Sex>true</Sex>
</Person>
(13)XML的使用建議
在服務(wù)端,C#代碼中:
1. 建議不用使用低級(jí)別的XML API來(lái)使用XML,除非你是在設(shè)計(jì)框架或者通用類庫(kù)。
2. 建議使用序列化、反序列化的方法來(lái)生成或者讀取XML
3. 當(dāng)需要考慮使用XML時(shí),先不要想著XML結(jié)構(gòu),先應(yīng)該定義好數(shù)據(jù)類型。
4. 列表節(jié)點(diǎn)不要使用[XmlElement],它會(huì)讓所有子節(jié)點(diǎn)【升級(jí)】,顯得結(jié)構(gòu)混亂。
5. 如果希望序列化的XML長(zhǎng)度小一點(diǎn),可以采用[XmlAttribute],或者指定一個(gè)更短小的別名。
6. 不要在一個(gè)列表中輸出不同的數(shù)據(jù)類型,這樣的XML結(jié)構(gòu)的可讀性不好。
7. 盡量使用UTF-8編碼,不要使用GB2312編碼。
在客戶端,JavaScript代碼中,我不建議使用XML,而是建議使用JSON來(lái)代替XML,因?yàn)椋?BR>1. XML文本的長(zhǎng)度比JSON要長(zhǎng),會(huì)占用更多的網(wǎng)絡(luò)傳輸時(shí)間(畢竟數(shù)據(jù)保存在服務(wù)端,所以傳輸是免不了的)。
2. 在JavaScritp中使用XML比較麻煩(還有瀏覽器的兼容問(wèn)題),反而各種瀏覽器對(duì)JSON有非常好的支持。
(14)反序列化的使用總結(jié)
如果XML是由類型序列化得到那的,那么反序列化的調(diào)用代碼是很簡(jiǎn)單的,反之,如果要面對(duì)一個(gè)沒(méi)有類型的XML,就需要我們先設(shè)計(jì)一個(gè)(或者一些)類型出來(lái),這是一個(gè)逆向推導(dǎo)的過(guò)程,請(qǐng)參考以下步驟:
1. 首先要分析整個(gè)XML結(jié)構(gòu),定義與之匹配的類型,
2. 如果XML結(jié)構(gòu)有嵌套層次,則需要定義多個(gè)類型與之匹配,
3. 定義具體類型(一個(gè)層級(jí)下的XML結(jié)構(gòu))時(shí),請(qǐng)參考以下表格。

(1)自定義序列化的實(shí)現(xiàn)方式
可以通過(guò)在對(duì)象上實(shí)現(xiàn) ISerializable 接口來(lái)自定義序列化過(guò)程。這一功能在反序列化后成員變量的值失效時(shí)尤其有用,但是需要為變量提供值以重建對(duì)象的完整狀態(tài)。要實(shí)現(xiàn) ISerializable,需要實(shí)現(xiàn) GetObjectData()方法以及一個(gè)特殊的構(gòu)造函數(shù),在反序列化對(duì)象時(shí)要用到此構(gòu)造函數(shù)。
(2)示例程序
[Serializable]
public class Person : ISerializable
{
public string Name;
public bool Sex;
public Person() { }
//必須的夠著方法,反序列化時(shí)調(diào)用
protected Person(SerializationInfo info, StreamingContext context)
{
Name = info.GetString("姓名");
Sex = info.GetBoolean("性別");
}
//序列化時(shí)調(diào)用
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("姓名", Name + "(自定義序列化)");
info.AddValue("性別", Sex);
}
public override string ToString()
{
return "姓名:" + this.Name + "\t性別:" + (this.Sex ? "男" : "女");
}
}
class Program
{
static void Main(string[] args)
{
Person p = new Person();
p.Name = "李志偉A";
p.Sex = true;
//使用二進(jìn)制序列化對(duì)象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件名稱與路徑
Stream fStream = new FileStream(fileName, FileMode.Create);
BinaryFormatter binFormat = new BinaryFormatter();//創(chuàng)建二進(jìn)制序列化器
binFormat.Serialize(fStream, p);//序列化對(duì)象
//使用二進(jìn)制反序列化對(duì)象
fStream.Position = 0;//重置流位置
p = (Person)binFormat.Deserialize(fStream);//反序列化對(duì)象
Console.WriteLine(p);
fStream.Dispose();//關(guān)閉文件
Console.WriteLine("OK!");
Console.Read();}
}
注意:在序列化過(guò)程中調(diào)用 GetObjectData()時(shí),需要填充方法調(diào)用中提供的 SerializationInfo對(duì)象。只需按名稱/值對(duì)的形式添加將要序列化的變量。其名稱可以是任何文本。只要已序列化的數(shù)據(jù)足以在反序列化過(guò)程中還原對(duì)象,便可以自由選擇添加至 SerializationInfo 的成員變量。如果基對(duì)象實(shí)現(xiàn)了 ISerializable,則派生類應(yīng)調(diào)用其基對(duì)象的 GetObjectData()方法。同樣,在反序列化時(shí)也會(huì)調(diào)用含有(SerializationInfo info, StreamingContext context)參數(shù)的特殊的夠著方法!否者將無(wú)法反序列化?。?!
相關(guān)文章
深入C# winform清除由GDI繪制出來(lái)的所有線條或圖形的解決方法
本篇文章是對(duì)在C#中使用winform清除由GDI繪制出來(lái)的所有線條或圖形的方法進(jìn)行了詳細(xì)的分析介紹,需要的朋友參考下2013-05-05WinForm中DefWndProc、WndProc與IMessageFilter的區(qū)別
這篇文章主要介紹了WinForm中DefWndProc、WndProc與IMessageFilter的區(qū)別,較為詳細(xì)的分析了WinForm的消息處理機(jī)制,需要的朋友可以參考下2014-08-08C#使用Gembox.SpreadSheet向Excel寫(xiě)入數(shù)據(jù)及圖表的實(shí)例
下面小編就為大家分享一篇C#使用Gembox.SpreadSheet向Excel寫(xiě)入數(shù)據(jù)及圖表的實(shí)例,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過(guò)來(lái)看看吧2017-12-12C# Oracle數(shù)據(jù)庫(kù)操作類實(shí)例詳解
這篇文章主要介紹了C# Oracle數(shù)據(jù)庫(kù)操作類實(shí)例,進(jìn)行數(shù)據(jù)庫(kù)操作時(shí)很有實(shí)用價(jià)值,需要的朋友可以參考下2014-07-07C#面向?qū)ο缶幊讨幸蕾嚪崔D(zhuǎn)原則的示例詳解
在面向?qū)ο缶幊讨?,SOLID?是五個(gè)設(shè)計(jì)原則的首字母縮寫(xiě),旨在使軟件設(shè)計(jì)更易于理解、靈活和可維護(hù)。本文將通過(guò)實(shí)例詳細(xì)講講C#面向?qū)ο缶幊讨幸蕾嚪崔D(zhuǎn)原則,需要的可以參考一下2022-07-07C#實(shí)現(xiàn)汽車租賃系統(tǒng)項(xiàng)目
這篇文章主要為大家詳細(xì)介紹了C#實(shí)現(xiàn)汽車租賃系統(tǒng)項(xiàng)目,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-01-01C# 啟用事務(wù)提交多條帶參數(shù)的SQL語(yǔ)句實(shí)例代碼
這篇文章主要介紹了C# 啟用事務(wù)提交多條帶參數(shù)的SQL語(yǔ)句實(shí)例代碼,需要的朋友可以參考下2018-02-02