Я пытаюсь сериализовать/десериализовать объект, содержащий Dictionary<Tuid,Section>
. Это нестандартные типы.
В моем коде у меня есть тип Template, который содержит Dictionary<Tuid,Section>
. Это класс Шаблон, который я пытаюсь сериализовать /deserialze.
Чтобы решить проблему, что эта коллекция является Словарем, я реализовал интерфейс ISerializable
в моем классе шаблонов....
[Serializable]
public class Template : ISerializable
{
protected Template(SerializationInfo info, StreamingContext context)
{
// Deserialize the sections
List<Tuid> tuids = (List<Tuid>)info.GetValue("Sections_Keys", typeof(List<Tuid>));
List<Section> sections = (List<Section>)info.GetValue("Sections_Values", typeof(List<Section>));
this._sections = new Dictionary<Tuid, Section>();
for (int i = 0; i < tuids.Count; i++)
{
_sections.Add(tuids[i], sections[i]);
}
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
List<Tuid> tuids = new List<Tuid>();
List<Section> sections = new List<Section>();
foreach (KeyValuePair<Tuid, Section> kvp in _sections)
{
tuids.Add(kvp.Key);
sections.Add(kvp.Value);
}
info.AddValue("Sections_Keys", tuids, typeof(List<Tuid>));
info.AddValue("Sections_Values", sections, typeof(List<Section>));
}
Стратегия здесь состоит в том, чтобы "распаковать" словарь в два отдельных списка и сохранить их отдельно в сериализованном потоке. Затем они снова создаются.
Мой класс Раздел также включает ISerializable
...
[Serializable]
public class Section : BaseObject
{
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// code
}
}
Проблема в том, что когда я сериализую GetObjectData()
вызывается как на моем шаблоне, так и на моем разделе, что заставляет меня думать, что данные являются Serializable и что он становится сериализованным.
Когда я десериализуюсь, вызывается только конструктор десериализации на Шаблон. Конструктор десериализации для раздела никогда не вызывается. Результатом этого является то, что вызов info.GetValue("Section_Values"....)
возвращает список, но в нем есть один элемент и этот элемент имеет значение null.
Почему мой конструктор для десериализации раздела никогда не вызван? Может быть, некоторые данные внутри раздела не сериализуемы? Если да, то как узнать, что именно он не может сериализовать?
Обновление. Одна вещь, которую я только что заметил, - это то, что раздел BaseObject помечается [Serializable]
, но не реализует ISerializable
.
Кроме того, мне интересно, как суетливый код Deserialize - будет ли он нацелен на конструктор, который также создает базовый класс?
Update..
Хорошо, Ive отследил проблему до сериализации секции. Код выглядит примерно так:
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
//info.AddValue("CustomObject", ClientInfo, typeof(CustomObject));
//info.AddValue("Description", Description, typeof(string));
}
Когда обе строки закомментированы, ничто не сериализуется, а конструктор десериализации вызывается на Section
. Если я добавлю в значение строки, все будет хорошо. Однако да, вы уже догадались - если я добавлю CustomObject
в поток сериализации, тогда конструктор десериализации не вызывается.
Обратите внимание, что...
- Конструктор десериализации для
Section
- пустой метод. Я не пытаюсь ничего сделать с десериализованными данными. - Базовый конструктор для раздела был заглушен, чтобы передать новые действительные объекты, и я подтвердил, что это нормально.
- Не исключены исключения, чтобы сказать, что
CustomObject
не может быть сериализован. -
CustomObject
является сериализуемым, и его методGetObjectData()
работает отлично, и его сконструировано отлично при десериализации.
Кажется странным, что просто добавляя этот сериализуемый объект к потоку, который затем просто не выполняет конструктор десериализатора Section
!!
Почему это может произойти?