МИНИСТЕРСТВО ОБРАЗОВАНИЯ И НАУКИ РФ
ГОСУДАРСТВЕННОЕ ОБРАЗОВАТЕЛЬНОЕ УЧРЕЖДЕНИЕ
ВЫСШЕГО ПРОФЕССИОНАЛЬНОГО ОБРАЗОВАНИЯ
«ДОНСКОЙ ГОСУДАРСТВЕННЫЙ ТЕХНИЧЕСКИЙ УНИВЕРСИТЕТ»
Кафедра «Программное обеспечение вычислительной техники и автоматизированных систем»
СЕРИАЛИЗАЦИЯ ОБЪЕКТОВ В СРЕДЕ .NET
Методические указания к лабораторной работе №8
по дисциплине «Межплатформенные языковые среды»
Ростов-на-Дону, 2011 г.
Составители: к.т.н., доц. Долгов В.В., доц. Деревянкина А.А.
УДК 512.3
Описание интерфейсов и работа с событиями: методические указания – Ростов н/Д: Издательский центр ДГТУ, 2011. – 8 с.
В методической разработке рассматривается назначение механизма сериализации объектов и использование различных форм сериализации при написании приложений. Описаны классы и атрибуты, управляющие процессом сериализации. Даны задания к лабораторным работам помогающим закрепить на практике полученные знания. Методические указания предназначены для студентов специальностей 230105 "Программное обеспечение вычислительной техники и автоматизированных систем", 010503 "Математическое обеспечение и администрирование информационных систем".
Ответственный редактор: д.т.н., проф. Нейдорф Р.А.
В.В. Долгов,
А.А. Деревянкина, 2011
Издательский центр ДГТУ, 2011
В терминах .NET сериализация – это процесс преобразования объекта в форму в которой он может быть сохранен на внешнем носителе или передан по сети передачи данных между различными вычислительными системами. Обратный процесс восстановления объектов из данных называется десериализацией. В стандартной реализации библиотеки .NET содержится два класса сериализации объектов – BinaryFormatter и SoapFormatter. BinaryFormatter удобен в использовании, когда необходимо получить небольшой по размеру образ объектов, в совокупности с быстрым и простым способом программирования. Кроме того, BinaryFormatter в отличие от XML/SOAP форматирования сохраняет полную структуру объекта, как он представлен в памяти компьютера, сохраняя значения, в том числе private полей.
Двоичная сериализация
Для того чтобы некий объект мог быть сериализован, его класс (в самом простейшем варианте) достаточно пометить атрибутом Serializable. Это необходимое и достаточное условие для сохранения данных объекта заданного класса.
В некоторых случаях классы содержат поля, хранящие либо постоянные значения, либо значения, которые после сериализации/десериализации могут не иметь смысла, или не могут сохраняться по соображениям безопасности. Такие поля необходимо пометить атрибутом NonSerialized. Например,
[Serializable]
public class CarEngine
{
private readonly int engineId;
[NonSerialized] public int temperature;
public bool TurnOn();
public bool TurnOff();
}
Атрибут Serializable НЕ наследуется. Таким образом, если возникает необходимость сериализации классов наследников, каждый из них должен быть помечен соответствующим атрибутом. В противном случае любая попытка обращения к подсистеме сериализации .NET для данного класса будет приводить к исключению SerializationException.
Для того чтобы сериализовать приведенный выше класс CarEngine в двоичном виде достаточно написать следующий код:
public void SerializeCarTo(string fileName, CarEngine care)
{
Stream st = new FileStream(fileName, FileMode.Create);
IFormatter f = new BinaryFormatter();
f.Serialize(st, care);
st.Close();
}
а для чтения сохраненного объекта из файла подойдет функция
public CarEngine DeserializeCarFrom(string fileName)
{
Stream st = new FileStream(fileName, FileMode.Open, FileAccess.Read);
IFormatter f = new BinaryFormatter();
CarEngine car = f.Deserialize(st);
st.Close();
return car;
}
Xml/soap-сериализация
Сериализация программных объектов в формат XML связанно с использованием вместо класса BinaryFormatter другого специального объекта XmlSerializer описанного в пространстве имен System.Xml.Serialization. XML-сериализация производит сохранение только полей и свойств имеющих область видимости public. Сохраняемые свойства должны быть доступны как для чтения, так и для записи, и исключение делается только для свойств поддерживающих интерфейс IList. По умолчанию, сериализатор при записи объекта создает XML следующего вида
<тип-объекта>
<имя-поля>значение-поля</имя-поля>
...
</тип-объекта>
записывая все public поля, доступные на чтение/запись. Для игнорирования некоторых полей и исключения их из процесса записи можно использовать атрибут XmlIgnoreAttribute выполняющий ту же функцию что и атрибут NoSerialized при двоичной сериализации.
В случаях, когда сериализация выполняется в целях обмена информацией с другими системами, или в случаях, когда на XML наложена строгая схема, определяющая имена элементов и атрибутов, имена элементов в XML могут не совпадать с именами полей, объявленных в программных объектах. Для реализации такой возможности предназначен атрибут XmlElementAttribute, изменяющий имя элемента XML-файла. Ещё одной возможностью является запись полей объекта в виде атрибутов вместо полей.
public class Book {
[XmlAttribute(“Name-Author”)]
public string Author = “неизвестен”;
public string ISBN;
}
Результатом будет получен xml-строка следующего вида:
<?xml version="1.0" encoding="utf-16"?>
<Book Name-Author="Неизвестен">
<ISBN>11234</ISBN>
</Book>
Сериализация коллекций производиться по общему формату
<имя-поля-коллекции>
<тип-элемента-коллекции>
поля объекта в коллекции
</тип-элемента-коллекции>
</имя-поля-коллекции>
Применяя к полю атрибут XmlArrayAttribute можно заменить имя элемента для поля-коллекции.
public class Book {
[XmlAttribute(“Name-Author”)]
public string Author = “неизвестен”;
public string ISBN;
[XmlArray(“par-list”), XmlArrayItem(“par”)]
public string[] Paragraphs;
}
Атрибут XmlArrayItemAttribute изменяет соответственно имя элементов, вложенных в основной элемент коллекции.
<?xml version="1.0" encoding="utf-16"?>
<Book Name-Author="Неизвестен">
<ISBN>11234</ISBN>
<par-list>
<par>1</par>
<par>2</par>
</par-list>
</Book>
Надо учитывать, что если коллекция может содержать различные классы, то тип каждого из них необходимо указать с помощью параметра type атрибута XmlArrayItem.