c#對象反序列化與對象序列化示例詳解。本站提示廣大學習愛好者:(c#對象反序列化與對象序列化示例詳解)文章只能為提供參考,不一定能成為您想要的結果。以下是c#對象反序列化與對象序列化示例詳解正文
1.對象序列化的引見
(1).NET支撐對象序列化的幾種方法
二進制序列化:對象序列化以後是二進制情勢的,經由過程BinaryFormatter類來完成的,這個類位於System.Runtime.Serialization.Formatters.Binary定名空間下。
SOAP序列化:對象序列化以後的成果相符SOAP協定,也就是可以經由過程SOAP 協定傳輸,經由過程System.Runtime.Serialization.Formatters.Soap定名空間下的SoapFormatter類來完成的。
XML序列化:對象序列化以後的成果是XML情勢的,經由過程XmlSerializer 類來完成的,這個類位於System.Xml.Serialization定名空間下。XML序列化不克不及序列化公有數據。
(2)幾種序列化的差別
二進制格局和SOAP格局可序列化一個類型的一切可序列化字段,不論它是公共字段照樣公有字段。XML格局僅能序列化公共字段或具有公共屬性的公有字段,未經由過程屬性地下的公有字段將被疏忽。
應用二進制格局序列化時,它不只是將對象的字段數據停止耐久化,也耐久化每一個類型的完整限制稱號和界說法式集的完全稱號(包含包稱、版本、公鑰標志、區域性),這些數據使得在停止二進制格局反序列化時亦會停止類型檢討。SOAP格局序列化經由過程應用XML定名空間來耐久化原始法式集信息。而XML格局序列化不會保留完全的類型稱號或法式集信息。這方便XML數據表示情勢更有終端開放性。假如願望盡量延長耐久化對象圖的應用規模時,SOAP格局和XML格局是幻想選擇。
(3)應用特征對序列化的掌握
要讓一個對象支撐.Net序列化辦事,用戶必需為每個聯系關系的類加上[Serializable]特征。假如類中有些成員不合適介入序列化(好比:暗碼字段),可以在這些域前加上[NonSerialized]特征。
2.應用二進制序列化和反序列化
(1)二進制序列化與反序列化的法式示例
[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;//編程說話
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程說話:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//創立Programmer列表,並添加對象
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"));
//應用二進制序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.dat";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
BinaryFormatter binFormat = new BinaryFormatter();//創立二進制序列化器
binFormat.Serialize(fStream, list);
//應用二進制反序列化對象
list.Clear();//清空列表
fStream.Position = 0;//重置流地位
list = (List<Programmer>)binFormat.Deserialize(fStream);//反序列化對象
foreach (Programmer p in list)
{
Console.WriteLine(p);
}
Console.Read();
}
}
(2)總結
應用二進制序列化,必需為每個要序列化的的類和其聯系關系的類加上[Serializable]特征,對類中不須要序列化的成員可使用[NonSerialized]特征。
二進制序列化對象時,能序列化類的一切成員(包含公有的),且不須要類有沒有參數的結構辦法。
應用二進制格局序列化時,它不只是將對象的字段數據停止耐久化,也耐久化每一個類型的完整限制稱號和界說法式集的完全稱號(包含包稱、版本、公鑰標志、區域性),這些數據使得在停止二進制格局反序列化時亦會停止類型檢討。所以反序列化時的運轉情況要與序列化時的運轉情況要雷同,否者能夠會沒法反序列化勝利。
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;//編程說話
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程說話:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//實例化對象
Programmer p = new Programmer("李志偉", true, "C、C#、C++、Java");
//應用SOAP序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create, FileAccess.ReadWrite);
SoapFormatter soapFormat = new SoapFormatter();//創立SOAP序列化器
soapFormat.Serialize(fStream, p);//SOAP不克不及序列化泛型對象
//應用SOAP反序列化對象
fStream.Position = 0;//重置流地位
p = null;
p = (Programmer)soapFormat.Deserialize(fStream);
Console.WriteLine(p);
Console.Read();
}
}
(2)總結
SOAP序列化與二進制序列化的差別是:SOAP序列化不克不及序列化泛型類型。與二進制序列化一樣在序列化時不須要向序列化器指定序列化對象的類型。而XML序列化須要向XML序列化器指定序列化對象的類型。
4.應用XML方法序列化和反序列化
(1)XML序列化與反序列化的法式示例
public class Person
{
public string Name;//姓名
public bool Sex;//性別,能否是男
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
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;//編程說話
public Programmer() { }//必需供給無參結構器,不然XmlSerializer將失足
public Programmer(string name, bool sex, string language) : base(name, sex)
{
this.Language = language;
}
public override string ToString()
{
return base.ToString() + "\t編程說話:" + this.Language;
}
}
class Program
{
static void Main(string[] args)
{
//創立Programmer列表,並添加對象
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序列化對象
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) }
);//創立XML序列化器,須要指定對象的類型
xmlFormat.Serialize(fStream, list);
//應用XML反序列化對象
fStream.Position = 0;//重置流地位
list.Clear();
list = (List<Programmer>)xmlFormat.Deserialize(fStream);
foreach (Programmer p in list)
{
Console.WriteLine(p);
}
Console.Read();
}
}
(2)總結
應用XML序列化或反序列化時,須要對XML序列化器指定須要序列化對象的類型和其聯系關系的類型。
XML序列化只能序列化對象的私有屬性,而且請求對象有一個無參的結構辦法,否者沒法反序列化。
[Serializable]和[NonSerialized]特征對XML序列化有效!所以應用XML序列化時不須要對對象增長[Serializable]特征。
5.XML序列化對象詳解
(1)解釋
本節重要引見:應用特征掌握對象序列化成XML文件的格局。
(2)應用XmlElement(默許值)
類聲明:
public class Person
{
[XmlElement]
public string Name;//應用[XmlElement]特征
public bool Sex;//默許應用了[XmlElement]特征
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
序列化生成的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() { }//必需供給無參結構器,不然XmlSerializer將失足
}
序列化生成的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() { }//必需供給無參結構器,不然XmlSerializer將失足
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="..."Sex="true">李志偉</Person>
(5)應用XmlType和XmlAttribute(重定名節點稱號)
類聲明:
[XmlType("小我信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
序列化生成的XML文件:
<小我信息xmlns:xsi="..."xmlns:xsd="..."姓名="李志偉"性別="true" />
(6)列表和數組的序列化
類聲明:
[XmlType("小我信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
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序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(Person[]));
xmlFormat.Serialize(fStream, ps);//序列化對象
fStream.Dispose();//封閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<ArrayOf小我信息xmlns:xsi="..."xmlns:xsd="...">
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
</ArrayOf小我信息>
留意:發明此時的XML文件的根節點稱號變了。此時要重定名根節點應應用以下方法:
[XmlType("小我信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
[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序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對象
fStream.Dispose();//封閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<人員信息xmlns:xsi="..."xmlns:xsd="...">
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
</人員信息>
(7)列表和數組的做為數據成員的序列化
類聲明:
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
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序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對象
fStream.Dispose();//封閉文件
Console.WriteLine("OK!");
Console.Read();
}
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<Array>
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
</Array>
<Person姓名="李志偉"性別="true" />
</PersonArray>
留意:假定這裡須要為Array和Person的節點重定名,代碼以下:
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
public class PersonArray
{
[XmlArrayItem("小我信息")]
[XmlArray("人員信息")]
public List<Person> Array=new List<Person>();
public Person Person = new Person();
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<人員信息>
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
</人員信息>
<Person姓名="李志偉"性別="true" />
</PersonArray>
留意:把“人員信息”節點去失落呢(直接湧現“小我信息”節點)
[XmlType("信息")]
public class Person
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
public class PersonArray
{
[XmlElement("小我信息")]
public List<Person> Array=new List<Person>();
public Person Person = new Person();
}
序列化生成的XML文件:
<PersonArrayxmlns:xsi="..."xmlns:xsd="...">
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<小我信息姓名="李志偉"性別="true" />
<Person姓名="李志偉"性別="true" />
</PersonArray>
(8)類型繼續與反序列化
類聲明:
public class Base { }
[XmlType("信息A")]
public class PersonA : Base
{
[XmlAttribute("姓名")]
public string Name;
[XmlAttribute("性別")]
public bool Sex;
public PersonA() { }//必需供給無參結構器,不然XmlSerializer將失足
}
[XmlType("信息B")]
public class PersonB : Base
{
[XmlElement("姓名")]
public string Name;
[XmlElement("年紀")]
public int Age;
public PersonB() { }//必需供給無參結構器,不然XmlSerializer將失足
}
[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序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create);
XmlSerializer xmlFormat = new XmlSerializer(typeof(PersonArray));
xmlFormat.Serialize(fStream, ps);//序列化對象
fStream.Dispose();//封閉文件
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>
</人員信息>
留意:同時為列表成員指定多個[XmlArrayItem(typeof(XXX))]可完成多種派生類型混在一路輸入。
(9)消除不須要序列化的成員
類聲明:
public class Person
{
public string Name;
[XmlIgnore]// 這個屬性將不會介入序列化
public bool Sex;
public Person() { }
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="...">
<Name>李志偉</Name>
</Person>
(10)強迫指定成員的序列化次序
類聲明:
public class Person
{
[XmlElement(Order = 2)]
public string Name;
[XmlElement(Order = 1)]
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
}
序列化生成的XML文件:
<Personxmlns:xsi="..."xmlns:xsd="...">
<Sex>true</Sex>
<Name>李志偉</Name>
</Person>
(11)自界說序列化行動
類聲明:
public class Person : IXmlSerializable
{
public string Name;
public bool Sex;
public Person() { }//必需供給無參結構器,不然XmlSerializer將失足
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)序列化設置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的應用建議
在辦事端,C#代碼中:
1. 建議不消應用初級其余XML API來應用XML,除非你是在設計框架或許通用類庫。
2. 建議應用序列化、反序列化的辦法來生成或許讀取XML
3. 當須要斟酌應用XML時,先不要想著XML構造,先應當界說好數據類型。
4. 列表節點不要應用[XmlElement],它會讓一切子節點【進級】,顯得構造凌亂。
5. 假如願望序列化的XML長度小一點,可以采取[XmlAttribute],或許指定一個更短小的別號。
6. 不要在一個列表中輸入分歧的數據類型,如許的XML構造的可讀性欠好。
7. 盡可能應用UTF-8編碼,不要應用GB2312編碼。
在客戶端,JavaScript代碼中,我不建議應用XML,而是建議應用JSON來取代XML,由於:
1. XML文本的長度比JSON要長,會占用更多的收集傳輸時光(究竟數據保留在辦事端,所以傳輸是免不了的)。
2. 在JavaScritp中應用XML比擬費事(還有閱讀器的兼容成績),反而各類閱讀器對JSON有異常好的支撐。
(14)反序列化的應用總結
假如XML是由類型序列化獲得那的,那末反序列化的挪用代碼是很簡略的,反之,假如要面臨一個沒有類型的XML,就須要我們先設計一個(或許一些)類型出來,這是一個逆向推導的進程,請參考以下步調:
1. 起首要剖析全部XML構造,界說與之婚配的類型,
2. 假如XML構造有嵌套條理,則須要界說多個類型與之婚配,
3. 界說詳細類型(一個層級下的XML構造)時,請參考以下表格。
6.自界說序列化(僅實用於二進制與SOAP)
(1)自界說序列化的完成方法
可以經由過程在對象上完成 ISerializable 接口來自界說序列化進程。這一功效在反序列化後成員變量的值掉效時特別有效,然則須要為變量供給值以重建對象的完全狀況。要完成 ISerializable,須要完成 GetObjectData()辦法和一個特別的結構函數,在反序列化對象時要用到此結構函數。
(2)示例法式
[Serializable]
public class Person : ISerializable
{
public string Name;
public bool Sex;
public Person() { }
//必需的夠著辦法,反序列化時挪用
protected Person(SerializationInfo info, StreamingContext context)
{
Name = info.GetString("姓名");
Sex = info.GetBoolean("性別");
}
//序列化時挪用
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;
//應用二進制序列化對象
string fileName = @"D:\users\lizw\桌面\Programmers.xml";//文件稱號與途徑
Stream fStream = new FileStream(fileName, FileMode.Create);
BinaryFormatter binFormat = new BinaryFormatter();//創立二進制序列化器
binFormat.Serialize(fStream, p);//序列化對象
//應用二進制反序列化對象
fStream.Position = 0;//重置流地位
p = (Person)binFormat.Deserialize(fStream);//反序列化對象
Console.WriteLine(p);
fStream.Dispose();//封閉文件
Console.WriteLine("OK!");
Console.Read();}
}
留意:在序列化進程中挪用 GetObjectData()時,須要填充辦法挪用中供給的 SerializationInfo對象。只需按稱號/值對的情勢添加將要序列化的變量。其稱號可所以任何文本。只需已序列化的數據足以在反序列化進程中復原對象,即可以自在選擇添加至 SerializationInfo 的成員變量。假如基對象完成了 ISerializable,則派生類應挪用其基對象的 GetObjectData()辦法。異樣,在反序列化時也會挪用含有(SerializationInfo info, StreamingContext context)參數的特別的夠著辦法!否者將沒法反序列化!!!