.NET / XML 序列化
本文旨在阐明序列化的概念。
引言
作为一名经常从互联网获取信息的开发者,我决定贡献一些自己的知识。我一直对 .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
。
由 CLR 调用以获取序列化数据,而void ISerializeble.GetObjectData (SerializationInfo info, StreamingContext ctxt)
用于根据序列化数据填充对象数据,通常通过远程调用接收。public MyObject(SerializationInfo info, StreamingContext ctxt)
在上述方法中,因为我们确切地知道要添加到序列化流中的内容,所以由于不使用反射,因此速度更快。如果我们的数据编码足够巧妙,我们可以从需要传输的数据量更小中获益。
关注点
如您所见,.NET 序列化与 XML 序列化完全不同。在我看来,XML 序列化应该仅用于将配置文件和选项类存储在注册表项中。
有关如何实现自定义序列化并提高性能的更多信息,请查看Tim Haynes 快速序列化文章,这篇文章最终让我弄清了我的想法。
我使用的任何术语,例如 .NET 序列化和 XML 序列化,都可能不准确。
历史
版本 1。