2016-07-13 2 views
2

Я вижу повсеместно belief (статья 2009 года) в Интернете, что класс Hashtable не является сериализуемым; однако я не могу найти никакой современной документации, которая поддерживает это понятие.Являются ли Hashtables Serializable?

Убеждение связано с еще одним документированным убеждением в том, что интерфейс IDictionary предотвращает сериализацию; однако я не могу найти что-либо в MSDN, который поддерживает это требование, сегодня.

Кроме того, Hashtable реализует ISerializable и содержит методы расширения, которые принимают информацию о сериализации.

Итак, в чем заключена сделка? Есть Hashtable сериализуемый? Где документация, поддерживающая это понятие, окружающее IDictionary?

Далее Разъяснение (пожалуйста, прочитайте):

утверждения, что IDictionary не сериализуемая поддерживаются большим количеством документации; однако это основное внимание уделяется использованию взаимодействий сериализации на основе XML с классом. ISerializable, как указано в комментариях ниже, а также через MSDN указывает, что класс сериализуем. Это также означает, что класс должен отвечать за собственную сериализацию.

Я думаю, что это отрицает утверждение, что Hashtable не является сериализуемым. Это, пожалуй, генезис моего вопроса.

+0

Существует не один к одному соответствию между «идеями, которые люди» и «вещи, которые документированы.» –

+0

@RobertHarvey уверен. Это правда. Но сказать, что что-то явно не сериализуемо, должно поддерживаться документацией, особенно если это что-то расширяет 'ISerializable'. Это кажется особенно сложным заявлением для поддержки использования таких библиотек, как NewtonSoft. – Thomas

+2

Он находится на [этой странице] (https://msdn.microsoft.com/en-us/library/ms950721.aspx): * «XmlSerializer не может обрабатывать классы, реализующие интерфейс IDictionary. Это было частично связано с ограничениями по расписанию и частично из-за того, что хэш-таблица не имеет аналога в системе типа XSD. Единственное решение - реализовать пользовательскую хеш-таблицу, которая не реализует интерфейс IDictionary ». * (Google - отличный инструмент). –

ответ

5

Распространенный вера настолько распространена, потому что это правда:

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()); 
} 

бросает

NotSupportedException: Тип System.Collections.Hashtable не поддерживается, поскольку он реализует IDictionary.

Это вовсе не означает, что это буквально невозможно сериализовать хэш-таблицу. Конечно, я могу просто перебирать все ключи и значения, записывать их в строку и затем восстанавливать хеш-таблицу. Просто я не могу полностью использовать инфраструктуру сериализации.

В чем причина? На самом деле это довольно просто - XmlSerializer предназначен для создания хорошего XML, в духе формата обмена XML. И XML не имеет никакого словаря или механизма «ключ-значение», который бы соответствовал. Поэтому, чтобы поддерживать сериализацию hashtable, им пришлось бы создать собственный «подформат» со своими собственными правилами. И назад, когда .NET разрабатывался, это был огромный no-no - XML ​​был обменом. Любое расширение (hah) в формат означает, что вы больше не совместимы, независимо от того, насколько хороша ваша идея.

Конечно, в настоящее время каждый и их бабушка производят XML-данные, которые не используются для обмена. И это не совсем плохо (в конце концов, файлы .NET config также являются XML-форматом). Но это тоже неправильно.

Напротив, возьмите что-нибудь наподобие BinaryFormatter. Это класс, где команда .NET разработала весь формат и не ограничивается стандартом. И вот и вот - BinaryFormatter может сериализовать и десериализовать Hashtable просто отлично.

Таким образом, немного более правильная вера заключалась бы в том, что «Hashtable не может быть сериализован для правильного стандартного XML. В частности, класс XmlSerializer выдает ошибку при попытке сериализации Hashtable».

+0

Я бывший разработчик Java. Я все еще привык к идее (подкрепленной здесь), что многие люди связывают слово «сериализация» с «XmlSerializer». – Thomas

+0

@Thomas Это смешно, потому что, когда я начинал с Java, все ассоциированные Xml со всем в Java: P .NET (и, конечно же, с JVM-экосистемой) очень сложны, и у него много разных целей. Это хорошая идея, что некоторые объекты могут быть сериализованы в одном виде, но не в другом? Это определенно делает вещи намного менее абстрактными и плохими ООП, не так ли? И .NET сильно рекламировался вокруг веб-сервисов и SOAP, поэтому соединение с XML имеет большой смысл. 'XmlSerializer' очень специфичен тем, что он явно предназначен для создания хорошего XML; 'BinaryFormatter' имеет свой собственный формат. – Luaan

+0

Когда я покинул Java, я использовал аннотации Spring (которые под капотом есть XML). У меня есть личная неприязнь к XML (не более чем отвращение). Но, как Java J2EE (снова аннотации сделали свой путь, чтобы охватить XML), и, особенно, как инженер JavaScript, XML и сериализация (для меня) просто не так сильно связаны. Может быть, другое поколение? – Thomas

2

Поддерживает ли Hashtable ISerializable? Абсолютно:

public class Hashtable : IDictionary, ICollection, IEnumerable, ISerializable, IDeserializationCallback, ICloneable 

Можем ли мы сериализовать 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); 

Результат ... Ошибка, как вы ожидали

исключения типа «System.NotSupportedException» произошел в system.Xml.dll, но не были обработаны в пользовательском коде

Дополнительная информация: Тип 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(); 

результат .. . Нет ошибок ... Таким образом, проблема связана с IDictionary и XmlSerialization, но не все. Сериализация

Если вам действительно нужно сделать это для XML, ManoDestra была хорошая ссылка https://blogs.msdn.microsoft.com/adam/2010/09/10/how-to-serialize-a-dictionary-or-hashtable-in-c/

Также интересно, что XML Serialization упоминает, что вы не можете сериализовать беззнаковые longs или коллекции.

Microsoft XML Serialization (MSDN)

+0

Хорошо ответил. Спасибо за время и источники. – Thomas

Смежные вопросы