.NET中提供了哪些可进行序列化操作的类型?

我们已经理解了如何把一个类型声明为可序列化的类型,但是万里长征只走了第一步,具体完成序列化和反序列化的操作还需要一个执行这些操作的类型。为了序列化具体实例到某种专用的格式,.NET中提供了三种对象序列格式化类型:BinaryFormatter、SoapFormatter和XmlSerializer。.

(1)BinaryFormatter

顾名思义,BinaryFormatter可用于将可序列化的对象序列化成二进制的字节流,在前面Serializable特性的代码示例中已经展示过,这里不再重复展示。

(2)SoapFormatter

SoapFormatter致力于将可序列化的类型序列化成符合SOAP规范的XML文档以供使用。在.NET中,要使用SoapFormatter需要先添加对于SoapFormatter的引用:

using System.Runtime.Serialization.Formatters.Soap;

Note:SOAP是一种位于应用层的网络协议,它基于XML,并且是Web Service的基本协议。

(3)XmlSerializer

XmlSerializer并不仅仅针对那些标记了Serializable特性的类型,更为需要注意的是,Serializable和NonSerialized特性在XmlSerializer类型对象的操作中完全不起作用,取而代之的是XmlIgnore属性。XmlSerializer可以对没有标记Serializable特性的类型对象进行序列化,但是它仍然有一定的限制:

① 使用XmlSerializer序列化的对象必须显示地拥有一个无参数的公共构造方法;

因此,我们需要修改前面代码示例中的Person类,添加一个无参数的公共构造方法:

[Serializable]
public class Person
{
    ......
    public Person()
    {
    }
    ......
}

② XmlSerializer只能序列化公共成员变量;

因此,Person类中的私有成员_number便不能被XmlSerializer进行序列化:

[Serializable]
public class Person
{
    // 私有成员无法被XmlSerializer序列化
    private int _number;
}

(4)综合演示SoapFormatter和XmlSerializer的使用方法:

① 重新改写Person类

[Serializable]
public class Person
{
    // 私有成员无法被XmlSerializer序列化
    private int _number;
    // 使用NonSerialized特性标记此成员不可被BinaryFormatter和SoapFormatter序列化
    [NonSerialized]
    public string _name;
    // 使用XmlIgnore特性标记此成员不可悲XmlSerializer序列化
    [XmlIgnore]
    public string _univeristy;

    public Person()
    {
    }

    public Person(int i, string s, string u)
    {
        this._number = i;
        this._name = s;
        this._univeristy = u;
    }

    public override string ToString()
    {
        string result = string.Format("学号是:{0},姓名是:{1},大学是:{2}", _number, _name, _univeristy);
        return result;
    }
}

② 新增SoapFormatter和XmlSerializer的序列化和反序列化方法

#region 01.SoapFormatter
// 序列化对象-SoapFormatter
static byte[] SoapFormatterSerialize(Person p)
{
    // 使用Soap协议序列化
    IFormatter formatter = new SoapFormatter();
    using (MemoryStream ms = new MemoryStream())
    {
        formatter.Serialize(ms, p);
        return ms.ToArray();
    }
}

// 反序列化对象-SoapFormatter
static Person SoapFormatterDeSerialize(byte[] data)
{
    // 使用Soap协议反序列化
    IFormatter formatter = new SoapFormatter();
    using (MemoryStream ms = new MemoryStream(data))
    {
        Person p = formatter.Deserialize(ms) as Person;
        return p;
    }
} 
#endregion

#region 02.XmlSerializer
// 序列化对象-XmlSerializer
static byte[] XmlSerializerSerialize(Person p)
{
    // 使用XML规范序列化
    XmlSerializer serializer = new XmlSerializer(typeof(Person));
    using (MemoryStream ms = new MemoryStream())
    {
        serializer.Serialize(ms, p);
        return ms.ToArray();
    }
}

// 反序列化对象-XmlSerializer
static Person XmlSerializerDeSerialize(byte[] data)
{
    // 使用XML规范反序列化
    XmlSerializer serializer = new XmlSerializer(typeof(Person));
    using (MemoryStream ms = new MemoryStream(data))
    {
        Person p = serializer.Deserialize(ms) as Person;
        return p;
    }
} 
#endregion

③ 改写Main方法进行测试

static void Main(string[] args)
{
    Person obj = new Person(26, "Edison Chou", "CUIT");
    Console.WriteLine("原始对象为:");
    Console.WriteLine(obj.ToString());

    // 使用SoapFormatter序列化对象
    byte[] data1 = SoapFormatterSerialize(obj);
    Console.WriteLine("SoapFormatter序列化后:");
    Console.WriteLine(Encoding.UTF8.GetString(data1));
    Console.WriteLine();
    // 使用XmlSerializer序列化对象
    byte[] data2 = XmlSerializerSerialize(obj);
    Console.WriteLine("XmlSerializer序列化后:");
    Console.WriteLine(Encoding.UTF8.GetString(data2));

    Console.ReadKey();
}

示例运行结果如下图所示:

.NET中提供了哪些可进行序列化操作的类型?