65.9K
CodeProject 正在变化。 阅读更多。
Home

.NET / XML 序列化

starIcon
emptyStarIcon
starIcon
emptyStarIconemptyStarIconemptyStarIcon

1.45/5 (8投票s)

2007年10月12日

CPOL

2分钟阅读

viewsIcon

72663

本文旨在阐明序列化的概念。

引言

作为一名经常从互联网获取信息的开发者,我决定贡献一些自己的知识。我一直对 .NET 序列化有一些模糊的概念,昨天我终于弄明白了。互联网是一个很好的资源,但也可能极具误导性。本文试图阐明 .NET 序列化和 XML 序列化的概念。

背景

当我第一次查找“序列化”这个术语时,基本上都被重定向到解释如何将对象转换为 XML 表示的网站。让我们称之为 XML 序列化,我实际上并不喜欢这个术语。但是 .NET 序列化并非如此。它是通过 Remoting 传输数据的机制。

XML 序列化

互联网上大部分文章都弄错了。不需要将类标记为[Serializable]或实现ISerializable。XML 序列化实际上使用反射来查找任何公共属性或字段,然后创建相应的 XML 节点。反序列化也是如此。

这是一个示例通用类,用于根据对象生成 XML 字符串及其逆过程

public class Serializer
{
    public static string ObjectToString(object obj)
    {
        try
        {
            XmlSerializer serializer = 
                new XmlSerializer(obj.GetType(), "");
            StringWriter writer = new StringWriter();
            serializer.Serialize(writer, obj, null);
            return writer.ToString();
        }
        catch(Exception)
        {
        }
        return null;
    }

    public static bool StringToObject(string data,out object obj)
    {
        obj = null; 
        try
        {
            XmlSerializer serializer = 
                    new XmlSerializer(obj.GetType(),"");
            StringReader reader = new StringReader(data);
            obj=serializer.Deserialize(reader);
            return true;
        }
        catch(Exception)
        {
        }
        return false;
    }
}

.NET 序列化

.NET 最显著的功能之一是序列化。此功能用于在远程调用之间传输数据。对于二进制传输协议,幕后会发生类似这样的事情

MemoryStream ms = new MemoryStream(); 
BinaryFormatter bFormatter = new BinaryFormatter();

序列化

bFormatter.Serialize(ms, objectToSerialize); 

反序列化

Object_Type obj = (Object_Type)bformatter.Deserialize(ms); 

要序列化的类必须用[Serializable]属性标记,并且可以选择实现ISerializable接口。.NET 自动化机制使用反射来查找需要序列化的内容。因为这不是 XML 序列化,所以实现IDictionary和其他接口的类无法序列化。

为了使反序列化工作,额外的信息会与实际的二进制数据一起包装,以某种方式描述哪些数据对应于什么。这使得生成的数据更大,但对于每个有效的可序列化类都能完成工作。

如果我们想覆盖此机制,则类必须实现ISerializeble

void ISerializeble.GetObjectData (SerializationInfo info, StreamingContext ctxt)由 CLR 调用以获取序列化数据,而public MyObject(SerializationInfo info, StreamingContext ctxt)用于根据序列化数据填充对象数据,通常通过远程调用接收。

在上述方法中,因为我们确切地知道要添加到序列化流中的内容,所以由于不使用反射,因此速度更快。如果我们的数据编码足够巧妙,我们可以从需要传输的数据量更小中获益。

关注点

如您所见,.NET 序列化与 XML 序列化完全不同。在我看来,XML 序列化应该仅用于将配置文件和选项类存储在注册表项中。

有关如何实现自定义序列化并提高性能的更多信息,请查看Tim Haynes 快速序列化文章,这篇文章最终让我弄清了我的想法。

我使用的任何术语,例如 .NET 序列化和 XML 序列化,都可能不准确。

历史

版本 1。

© . All rights reserved.