Форум программистов
 

Восстановите пароль или Зарегистрируйтесь на форуме, о проблемах и с заказом рекламы пишите сюда - alarforum@yandex.ru, проверяйте папку спам!

Вернуться   Форум программистов > .NET Frameworks (точка нет фреймворки) > C# (си шарп)
Регистрация

Восстановить пароль
Повторная активизация e-mail

Купить рекламу на форуме - 42 тыс руб за месяц

Ответ
 
Опции темы Поиск в этой теме
Старый 29.03.2018, 11:51   #1
mike_ovch
Новичок
Джуниор
 
Регистрация: 29.03.2018
Сообщений: 4
По умолчанию Десериализуются не все свойства

Коллеги. Столкнулся с такой проблемой.
Создал класс для хранения словарей сопоставления данных из дух систем.
Класс содержит свойство Items, с коллекцией объектов, которые успешно сериализуются и десериализуются.
Все было хорошо, пока не понадобилось добавить в класс свойства для хранения имени и описания словаря.
Тут выяснилось, что значения в эти свойства (string) при десериализации не подтягиваются, хотя если из задать программно, - успешно сериализуются.
Никак не могу понять, что не так.

Проект для тестирования во вложении.

Код класса:
Код:
using System;
using System.Collections.Generic;
using System.Linq;
using System.IO;
using System.Xml;
using System.Xml.Serialization;

namespace Serialization_Test
{
    /// <summary>Двойной справочник для сопоставления данных из двух систем</summary>
    [Serializable]
    public class TwinReferenceBook
    {
        /// <summary>Имя словаря</summary>
        public string Name { set; get; }
        /// <summary>Описание словаря</summary>
        public string Description { set; get; }

        /// <summary>Перечень записей в словаре</summary>
        public List<TwinReference> Items { set; get; }

        /// <summary>Количество записей в словаре</summary>
        [XmlIgnore] public int ItemsCount => Items?.Count() ?? 0;


        #region Делегат для обновления содержимого справочника (RefreshDelegate RefreshFunc)
        /// <summary>Делегат для обновления содержимого справочника</summary>
        /// <returns>Перечень записей</returns>
        public delegate List<TwinReference> RefreshDelegate();

        /// <summary>Свойство: хранит метод обновления содержимого справочника</summary>
        [XmlIgnore]
        public RefreshDelegate RefreshFunc { set; get; }
        #endregion

        #region Свойства для проверки состояния объекта (не сериализуются)
        /// <summary>Загружен ли справочник</summary>
        [XmlIgnore]
        public bool IsLoaded => (
                (Items != null) &&
                (Items.Count > 0) &&
                (Items[0].SID != -1 || Items[0].SID != -1) &&
                (Items[0].SValue != "" || Items[0].GValue != "")
            );

        /// <summary>Свойство, сообщает, что метод словарь может быть обновлён</summary>
        [XmlIgnore]
        public bool IsRefreshable => RefreshFunc != null;

        #endregion

        #region Конструкторы
        public TwinReferenceBook() { }

        public TwinReferenceBook(string path, string name = "", string description = "")
        {
            Init();
            Load(path);
            Name = name;
            Description = description;
        }

        public TwinReferenceBook(RefreshDelegate refreshDelegate, string path, string name = "", string description = "")
            : this(path, name, description)
        {
            RefreshFunc = refreshDelegate;
        }
        #endregion

        #region Методы

        /// <summary>Обновляет элементы словаря, используя переданный делегат</summary>
        public void Refresh()
        {
            if (IsRefreshable)
                this.Items = RefreshFunc();
        }

        /// <summary>Загрузка справочника из XML файла</summary>
        public void Init()
        {
            Items = new List<TwinReference>();
        }

        /// <summary>Загрузка справочника из XML файла</summary>
        /// <param name="path">путь</param>
        public void Load(string path)
        {
            XmlSerializer serializer = new
                XmlSerializer(typeof(TwinReferenceBook));
            using (FileStream fs = new FileStream(path, FileMode.Open))
            {
                XmlReader reader = XmlReader.Create(fs);
                TwinReferenceBook import = (TwinReferenceBook)serializer.Deserialize(reader);
                this.Items = import.Items;
            }
        }

        /// <summary>Сохранение справочника в XML файл</summary>
        /// <param name="path">путь</param>
        public void Save(string path)
        {
            XmlSerializer serializer = new
                XmlSerializer(typeof(TwinReferenceBook));
            using (FileStream fs = new FileStream(path, FileMode.OpenOrCreate))
            {
                serializer.Serialize(fs, this);
            }
        }

        /// <summary>Добавление записи в словарь</summary>
        /// <param name="twinReference">запись словаря</param>
        public void Add(TwinReference twinReference)
        {
            if (Items == null)
                Init();
            Items.Add(twinReference);
        }

        #endregion
    }
}
Вложения
Тип файла: zip SerializationTest-20180329.zip (163.3 Кб, 10 просмотров)
mike_ovch вне форума Ответить с цитированием
Старый 29.03.2018, 12:30   #2
pu4koff
Старожил
 
Аватар для pu4koff
 
Регистрация: 22.05.2007
Сообщений: 9,520
По умолчанию

Может таки они сначала считываются из xml, а потом уже в них записывается пустая строка?
Код:
public TwinReferenceBook(string path, string name = "", string description = "")
        {
            Init();
            Load(path);
            Name = name;
            Description = description;
        }
pu4koff вне форума Ответить с цитированием
Старый 29.03.2018, 12:57   #3
mike_ovch
Новичок
Джуниор
 
Регистрация: 29.03.2018
Сообщений: 4
По умолчанию

Спасибо. Это было бы логично, но в тестовом проекте используется конструктор без параметров.
Конструкторы заменил (костыли от старой реализации. спасибо). Но результата это не принесло.

Новые конструкторы:
Код:
        #region Конструкторы
        public TwinReferenceBook() { }

        public TwinReferenceBook(string path)
        {
            Init();
            Load(path);
        }

        public TwinReferenceBook(RefreshDelegate refreshDelegate, string path, string name = "", string description = "")
            : this(path)
        {
            RefreshFunc = refreshDelegate;
        }
        #endregion
Вложения
Тип файла: zip SerializationTest-20180329-2.zip (163.2 Кб, 9 просмотров)

Последний раз редактировалось mike_ovch; 29.03.2018 в 13:06.
mike_ovch вне форума Ответить с цитированием
Старый 29.03.2018, 13:12   #4
mike_ovch
Новичок
Джуниор
 
Регистрация: 29.03.2018
Сообщений: 4
По умолчанию

Ответ найден. Проблема в методе Load. Из десериализованного объекта вытягивалось только свойство items.

Последний раз редактировалось mike_ovch; 29.03.2018 в 13:17. Причина: уточнение формулировки
mike_ovch вне форума Ответить с цитированием
Ответ


Купить рекламу на форуме - 42 тыс руб за месяц

Опции темы Поиск в этой теме
Поиск в этой теме:

Расширенный поиск


Похожие темы
Тема Автор Раздел Ответов Последнее сообщение
Не меняется размер формы, хотя все свойства верные. Nikolass44 Общие вопросы Delphi 20 15.04.2016 00:27
Необходимо создать класс, содержащий по возможности все его виды элементов: поля, конструкторы, свойства TGOD C# (си шарп) 8 13.10.2014 19:43
TableLayoutPanel, заблокированы все свойства! Fedosss C# (си шарп) 0 24.10.2013 03:06