分析問題
為了序列化具體實例到某種專業的格式,.NET提供了三種對象序列格式化類型:BinaryFormatter、SoapFormatter和XmlSerializer。
BinaryFormatter用於將可序列化的對象序列化成二進制的字節流,而SoapFormatter則致力於把可序列化的類型序列化成符合SOAP規範的XML文檔,以供使用。對於那些使用Serializable特性來申明成可序列化類型的對象,BinaryFormatter和SoapFormatter可以方便地把它們序列化成特定的格式。
説明
SOAP是一種位於應用層的網絡協議,它基於XML,並且是Web服務的基本協議,後續章節將覆蓋關於SOAP的面試題。
另外,.NET提供了一個執行序列化操作的類型XmlSerializer。不同於BinaryFormatter和SoapFormatter,XmlSerializer並不針對那些使用Serializable特性的類型,事實上,Serializable和NonSerialized特性在XmlSerializer類型對象的操作中完全不起作用,取而代之的是XmlIgnore屬性。XmlSerializer可以對沒有Serializable特性修飾的類型對象進行序列化,但它仍然有一定的限制:
1、使用XmlSerializer序列化的對象類型必須顯式地擁有一個無參的公共構造方法。
2、XmlSerializer只能序列化公共成員變量。
以下代碼展示了SoapFormatter和XmlSerializer類型的使用方法,首先為了演示起見,定義一個將被用來測試序列化的簡單類型。
using System;
using System.Text;
using System.Xml.Serialization;
using System.IO;
using System.Runtime.Serialization.Formatters.Soap;
namespace Test111
{
class DoSerialize
{
static void Main()
{
MyObject obj = new MyObject(10, "我是字符串");
Console.WriteLine("原始對象是:");
Console.WriteLine(obj);
//使用SoapFormatter進行序列化
byte[] data = SoapFormatterSerialize(obj);
Console.WriteLine("SoapFormatter序列化後:{0}\r\n",Encoding.UTF8.GetString(data));
//使用XmlSerializer進行序列化
byte[] data1 = XmlSerializerSerialize(obj);
Console.WriteLine("XmlSerializer序列化後:{0}\r\n", Encoding.UTF8.GetString(data1));
Console.Read();
}
//SoapFormatter序列化
static byte[] SoapFormatterSerialize(MyObject obj)
{
using (MemoryStream ms=new MemoryStream ())
{
SoapFormatter sf = new SoapFormatter();
sf.Serialize(ms, obj);
return ms.ToArray();
}
}
//SoapFormatter反序列化
static MyObject SoapFormatterDeSerialize(byte[] bytes)
{
using (MemoryStream ms=new MemoryStream (bytes))
{
SoapFormatter sf = new SoapFormatter();
return sf.Deserialize(ms) as MyObject;
}
}
//使用XmlSerializer序列化
static byte[] XmlSerializerSerialize(MyObject obj)
{
using (MemoryStream ms = new MemoryStream ())
{
XmlSerializer xs = new XmlSerializer(typeof(MyObject));
xs.Serialize(ms, obj);
return ms.ToArray();
}
}
//使用XmlSerializer反序列化
static MyObject XmlSerializerDeSerialize(byte[] bytes)
{
using (MemoryStream ms=new MemoryStream (bytes))
{
XmlSerializer xs = new XmlSerializer(typeof(MyObject));
return xs.Deserialize(ms) as MyObject;
}
}
}
[Serializable]
public class MyObject
{
//私有成員,不能被XmlSerializer序列化
private int _myInt;
//申明不可被序列化
[NonSerialized]
public string _myString1;
//申明不可被XmlSerializer序列化
[XmlIgnore]
public string _myString2;
public MyObject()
{
_myInt = 0;
_myString1 = string.Empty;
_myString2 = string.Empty;
}
public MyObject(int i, string s)
{
_myInt = i;
_myString1 = s;
_myString2 = s;
}
public override string ToString()
{
return new StringBuilder().AppendFormat("整數是:{0}\r\n字符串1是:{1}\r\n字符串2是:{2}",_myInt.ToString(),_myString1,_myString2).ToString();
}
}
}
答案
.NET內建類型提供了三個可執行序列化和反序列化操作的類型:BinaryFormatter、SoapFormatter和XmlSerializer。BinaryFormatter和SoapFormatter可以對那些有Serializable特性的類型進行序列化和反序列化操作,除了由NonSerialized特性修飾的成員,兩者將序列化所有其他的成員。而XmlSerializer不需要對對象類型申明Serializable特性,但它要求對象類型有一個顯式的無參公共構造方法,並且它不能序列化對象的非公共成員和由XmlIgnore修飾的成員。