. Я пытаюсь сериализовать / десериализовать объект, содержащий Dictionary
. Это оба пользовательских типа.
В моем коде есть тип шаблона , который содержит Dictionary
. Я пытаюсь сериализовать / десериализовать класс Template .
Чтобы решить проблему, заключающуюся в том, что эта коллекция является словарем, я реализовал интерфейс ISerializable
в моем классе Template ....
[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>));
}
Стратегия здесь состоит в том, чтобы «распаковать» словарь в два отдельных списка и сохраните их по отдельности в сериализованном потоке. Затем они создаются заново.
Мой класс Section также реализует ISerializable
...
[Serializable]
public class Section : BaseObject
{
protected Section(SerializationInfo info, StreamingContext context):base(.....)
{
// Code
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
// code
}
}
Проблема в том, что при сериализации GetObjectData ()
вызывается в обоих моих шаблонах и мой раздел, который заставляет меня поверить, что данные сериализуемы и что они сериализованы.
Когда я выполняю десериализацию, только вызывается конструктор десериализации в Template. Конструктор десериализации для Section никогда не вызывается. В результате вызов info.GetValue ("Section_Values" ....)
возвращает список, но в нем есть один элемент, и этот элемент является нулевым.
Почему мой конструктор для десериализации раздела никогда не вызывается? Может быть, некоторые данные внутри раздела не сериализуемы? Если да, то как узнать, что именно он не может сериализовать?
Обновление: я только что заметил одну вещь: раздел BaseObject for помечен как [Serializable]
, но не реализует ISerializable
.
Кроме того, мне интересно, насколько суетливым является код десериализации - будет ли он нацелен на конструктор, который также создает базовый класс?
Обновление ..
Хорошо, я отследил проблему до сериализации раздела. Код выглядит примерно так ...
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));
}
Когда закомментированы обе строки, ничего не сериализуется, и конструктор десериализации вызывается в Разделе
. Если я добавлю строковое значение, все будет в порядке. Однако да, как вы уже догадались, если я добавлю CustomObject
в поток сериализации, то конструктор десериализации не будет вызван.
Обратите внимание, что ...
раздела
- пустой метод - я не пытаюсь что-либо делать с десериализованными данными. CustomObject
не может быть сериализован. CustomObject
является сериализуемым, а его метод GetObjectData ()
работает нормально, а его построение отлично при десериализации. Кажется странным, что простое добавление этого сериализуемого объекта в поток, что структура затем просто терпит неудачу в конструкторе десериализатора из раздела
!!
Почему это могло произойти?