Полу урок: Сериализация.
По просьбе автора две части статьи были соединены в одну тему.
Все комментарии были перемещены в отдельную тему. Просьба комментарии теперь писать только туда, чтобы не засорять этот топик! - АВТОМАТ Сериализация обьектов .Вступление Думаю много кто из вас делал загрузку/сохранение пареметров программы/игры, и часто сталкивался с разными проблемами связаными с этим делом. Хотелось поделится опытом, услышать от вас идеи по улучшению. 1. Ввод в сериализацию Как гласит вика "Сериализация (в программировании) — процесс перевода какой-либо структуры данных в последовательность битов. Обратной к операции сериализации является операция десериализации — восстановление начального состояния структуры данных из битовой последовательности." То есть это сохранения наших классов, с их, состоянием в файл. C# даёт удобную(но далеко не идеальную) возможность для работы с сериализцией System.Xml.Serialization. Он записывает данные в файл в виде Xml структуры, что удобно, если нужно будет править файл вручную, и в общем-то читабельней. Минусом использования этого класса является то, что на сериализацию больших классов многократно (дупустим некое подобие базы данных) будет тратится довольно таки ощутимое время, что не совсем хорошо. Давайте попробуем обойти это 2. Один из способов избежать повторной сериализации структуры - сохранять шаблон, и при следующем вызове сериализации использовать его. Сейчас напишем базовый класс для нашого сериализатора. PHP код:
Примечание 2:для сериализатора нужно будет использовать следующие библиотеки PHP код:
Итак, давайте разберём по методом, что у нас есть. А есть у нас всего три метода, которые, пока что, как заглушки: GetSerializer(Type type) - метод который будет возвращать сериализатор для указанного типа - "Type type" WriteEntity(object obj, string fileFullPath) - метод который будет записывать в файл полученный объект (object obj) любого типа в файл (string fileFullPath). Путь к файлу желательно писать полный, во избежания недоразумений. T GetEntity<T>(string fileFullPath) - метод который будет производить десериализацию указанного файла (string fileFullPath) в тип T, и возвратит нам экземпляр этого класса(T). Давайте наполнять наш класс. Во первых, создадим хранилище для сериализаторов, в таком деле я предпочитаю использовать коллекцию типа Hashtable (хотя тут дело каждого можно использовать и обычный IDictionary<string,XmlSerializer>) PHP код:
Так как переменная у нас static, то можно сразу же её объявить, чтобы потом не переживать (хотя я рекомендую всё-таки делать конструкторы даже для статик классов). Идем дальше. Заходим в метод GetSerializer Обьявляем переменную для хранения возвращаемого сериализатора PHP код:
и так лочим нашу коллекцию PHP код:
Внутри попытаемся получить сериализатор из нашей коллекции, в которой сохранены имена типов, который уже были сериализованы, и собственно сам сериализатор. PHP код:
PHP код:
Вот собственно как должен после всего этого выглядеть метод PHP код:
Для начала создаём сериализатор, с использованием только что написанного нами метода. PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
PHP код:
Работать с этим классом так PHP код:
Пока что всё. Завтра напишу Про то как производить десериализацию из файла( а лучше не ждите и попробуйте сами сделать). а также про то, как назначить имена при сериализации и прочие нюансы. Удачи! З.Ы. Спасибо ffinder за корректуру. |
Полу урок. Сериализация. Часть 2. Десериализация и параметры.
В предыдущей статье мы получили такой код :
PHP код:
Это мы будем делать с помощью метода PHP код:
Выглядеть метод будет так PHP код:
PHP код:
PHP код:
в следующей строке, мы производим десериализацию из потока reader, с помощью полученного нами сериализатора deSerializer, и приводим его у требовавшемуся типу - Т который был указан при вызове метода: PHP код:
Вот пример кода: Объявляем класс TempClass: PHP код:
Далее: PHP код:
PHP код:
Далее вызываем наш метотод для сериализации в файл @"C:\classes.xml": PHP код:
PHP код:
PHP код:
Также поля, помеченные как приватные (а также как protected), тоже не сериализуются. Остальные поля сериализовались с именем прописанном в коде. В первом файле, поле Id будет равно 1, а во втором - 2, то есть можно быть уверенным что сериализовалось два разных экземпляра. Идём дальше по коду. PHP код:
Примечание: при десериализцаии вызывается конструктор по умолчанию (new()) который обязательно должен присутствовать в сериализуемом классе, также класс, который вы ходите сериализовать/десериализовать должен быть объявлен с модификатором видимости public. и свойства полученного нами экземпляра в консоль, чтобы наглядно увидеть. PHP код:
3. А сейчас давайте поговорим о нюансах и некоторых возможностях серилизации/десериализации. и так: 1) Возможность исключения из сериализации/десериализации не нужных полей: [XmlIgnore] ставится перед полем/свойством, которое мы не хотим чтобы сериализировалось в файл. Это может понадобится если ваш класс выполняет какие действия в свойствах, например, модифицируем на класс TempClass в класс MathClass и добавим ему несколько полей. PHP код:
SecondDigit. но так как результат у нас обновляется автоматически нам нет надобности записывать его в файл, и мы ставим перед ним [XmlIgnore]. остальные же поля будут сериализованы в файл. 2) В xml 3 типа структур: - ROOT - коренная структура, в которую входят все под структуры. В этой роли выступает класс, который был передан на сериализацию. в нашем примере это класс MathClass. Посмотрите в xml, и вы увидите что основная структура тоже называется MathClass, это корень. -Attribute - поля, которые будут записываться перед ">" начала текущей структуры. - Element - под структуры в текущей структуре - по умолчанию, для всех свойств/полей класса при сериализации. В общем то, представляет собой сериализацию того класса, который содержится в этом самом поле/свойстве Пример: PHP код:
Поставим перед полем Id модификатор PHP код:
PHP код:
Теперь установим свойства SecondDigit и FirstDigit элементами нашего класса PHP код:
На сегодня всё, мы разобрались как считать структуру из файла, смогли установить какие поля нам не нужны при сохранении, а также, как делать нужные нам свойства полями. В следующий раз я разберу как назначать мена сериализируемым объектам и ещё несколько нюансов, которые возникают при этом. До скорых! |
Полу урок: Сериализация. Части 3. Параметры
Вложений: 1
Всем привет!
Сегодня мы продолжим разбирать параметры сериализации/десериализации. У модификатор [XmlAttribute] есть конструктор PHP код:
Такойже конструктор есть и у элементов: PHP код:
PHP код:
PHP код:
Хотел бы вернутся к первому пункту в списке структур - Root Этому типу соответствует модификатор PHP код:
У него также есть конструктор, который позволяет задавать имя структуры PHP код:
PHP код:
PHP код:
Давайте ещё посмотрим пример, когда у класса есть поле другого класса, объявленного нами PHP код:
PHP код:
а также изменим немножко нашу основную функцию PHP код:
После сериализации мы увидим что в файле classes1, появилось свойство SubClass. Как видим поля, которые равны null, не сериализируется, если поле числового типа, то оно сериализируется в любом случае. Теперь хочу кое что сказать по поводу свойств, о их преймуществах при сериализации по сравнению с полями и членами класса(field,members). У свойств есть два поля - PHP код:
Заменим модификатор свойства SubClass на Код:
[XmlIgnore] Также добавим новое свойство - SubClassName: PHP код:
Далее... Отступление. Так как Си-шарп поддерживет ООП в полноймере, есть возможность зоздавать классы, наследуя их от других классов и интерфейсов. Часто бывает что нужно сериализовать множество разных классов, которые имеют общие поля. При использовании ООП, нет необходимости создвать несколько списков, для содержания разных типов обьектов. Тоесть движок игры, который обновляет состояния всех обьектов, а обьекты в свою очередь могут будь разных типов - 3д обьекты, 2д обькты, скрипты. Без ооп, нам бы пришлось держать 3 списка обьктов, чтобы обновлять их. Так как следующий код, довольно обьёмный по сравнению с предидущими, я не буду коментировать каждую строку, я думаю вы и сами разберётесь. PHP код:
Ткпкрь посмотрите на параметры модификатора XmlElementв классе ForSerialize . как видите, мы обьявили два модификатора для одного свойства объекта. Конструктор его такой - PHP код:
Это нужно для того, чтобы восстанавливать тип обьктов, от общего родителя как у нас. тоесть чтобы при сериализации Object3D десериализовался как Object3D а не просто ObjectBase. Изменим основной метод нашей программы, PHP код:
Структура этого файла будет выглядеть так - PHP код:
Со временем я возможно буду добавлять заметки в эту статью. Я прикрепил к посту проект, который был использован в последнем примере. В ближайшем будующем я возможно напишу статью по XNA. Удачи вам, и стремления к совершенству. |
Часовой пояс GMT +4, время: 06:38. |
vBulletin® Version 3.6.5.
Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
Перевод: zCarot