Tho*_*mas 3 .net c# serialization
我在整个互联网上看到一个普遍的信念(2009年的文章),该Hashtable课程不可序列化; 但是,我找不到任何支持这个概念的现代文档.
这种信念源于另一种记录错误的信念,即IDictionary界面阻止了序列化; 但是,我今天在MSDN中找不到支持此声明的任何内容.
此外,Hashtable实现ISerializable并包含接受序列化信息的扩展方法.
那么,这笔交易是什么?可Hashtable序列化吗?支持这一概念的文档在哪里IDictionary?
进一步澄清(请阅读):
IDictionary大量文档支持不可序列化的语句; 但是,这侧重于使用基于XML的序列化与类的交互.ISerializable正如下面的注释中所提到的,并且通过MSDN表明类是可序列化的.它还意味着必须负责其自身序列化的类.
我认为这否定了Hashtable不可序列化的说法.这可能是我的问题的起源.
普遍存在的信念是如此普遍,因为它是真的:
var t = new Hashtable();
t.Add("Hi!", "I'm here");
t.Add("Hm", "Yup");
var serializer = new XmlSerializer(typeof(Hashtable));
using (var sw = new StringWriter())
{
serializer.Serialize(sw, t);
Console.WriteLine(sw.ToString());
}
Run Code Online (Sandbox Code Playgroud)
投
NotSupportedException:不支持System.Collections.Hashtable类型,因为它实现了IDictionary.
这并不意味着序列化哈希表几乎是不可能的.当然,我可以遍历所有键和值,将它们写入字符串,然后从中重构哈希表.只是我不能完全使用序列化基础设施.
这是什么原因?它实际上非常简单 - XmlSerializer旨在生成良好的XML,本着XML的交换格式的精神设计.并且XML没有任何类型的字典或"键值"机制.因此,为了支持哈希表序列化,他们必须使用自己的规则制作自己的"子格式".回到.NET的设计时,这是一个巨大的禁忌 - XML是一种交换格式.对格式的任何扩展(hah)意味着你不再兼容,无论你有多么好的想法.
当然,如今,每个人和他们的祖母都在制作不用于交换目的的XML数据.而且这并不是一件坏事(毕竟,.NET config文件也是一种XML格式).但它也有点不对劲.
相反,采取类似的东西BinaryFormatter.这是一个.NET团队设计整个格式的类,并且不受标准的限制.而且 - 看哪 - BinaryFormatter可以序列化和反序列化一个Hashtable正常的.
因此,稍微更正确的信念是"Hashtable无法序列化为有效的标准XML.特别是当您尝试序列化Hashtable时,XmlSerializer类会抛出错误."
Hashtable是否实现了ISerializable?绝对:
public class Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable
Run Code Online (Sandbox Code Playgroud)
我们可以将Hashtable序列化为XML吗?我们来试试吧:
var hash = new System.Collections.Hashtable();
hash[7] = "7";
hash[8] = "8";
var serializer = new System.Xml.Serialization.XmlSerializer(typeof(System.Collections.Hashtable));
TextWriter writer = new System.IO.StreamWriter(@"C:\SomeFile.xml");
serializer.Serialize(writer, hash);
Run Code Online (Sandbox Code Playgroud)
结果...错误如您所料
System.Xml.dll中发生类型为"System.NotSupportedException"的异常,但未在用户代码中处理
附加信息:不支持System.Collections.Hashtable类型,因为它实现了IDictionary.
因此,看起来确实如此,.Net 4.5+仍然如此
但让我们再试一次二进制序列化......
var hash = new System.Collections.Hashtable();
hash[7] = "7";
hash[8] = "8";
var formatter = new System.Runtime.Serialization.Formatters.Binary.BinaryFormatter();
Stream stream = new FileStream(@"C:\SomeFolder\SomeFile.bin", FileMode.Create, FileAccess.Write, FileShare.None);
formatter.Serialize(stream, hash);
stream.Close();
Run Code Online (Sandbox Code Playgroud)
结果...没有抛出错误... 所以问题似乎与IDictionary和XmlSerialization有关,但不是所有序列化
如果你真的需要对XML做这个,ManoDestra有一个很好的链接https://blogs.msdn.microsoft.com/adam/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in -C/
另外,有趣的是,XML序列化提到你无法序列化未签名的long或集合.