- Фантастика и фэнтези
- Ироническое фэнтези
- Стимпанк
- Детективная фантастика
- Киберпанк
- Попаданцы
- LitRPG
- Космоопера
- Технофэнтези
- Городская фантастика
- Русское фэнтези
- Юмористическая фантастика
- Космическая фантастика
- Боевое фэнтези
- Эпическая фантастика
- Зарубежная фантастика
- Книги магов
- Мистика
- Разная фантастика
- Разное фэнтези
- Любовное фэнтези
- Романтическая фантастика
- Городское фентези
- Историческая фантастика
- Историческое фэнтези
- Социально-философская фантастика
- Сказочная фантастика
- Иностранное фэнтези
- Романтическое фэнтези
- Ироническая фантастика
- Ужасы и Мистика
- Постапокалипсис
- Героическая фантастика
- Фэнтези
- Научная Фантастика
- Социально-психологическая
- Альтернативная история
- Боевая фантастика
- Разная литература
- Пословицы, поговорки
- Шахматы
- Визуальные искусства
- Фанфик
- Авто и ПДД
- Военное
- Отраслевые издания
- Гиды, путеводители
- Зарубежная образовательная литература
- Военная история
- Цитаты из афоризмов
- Современная литература
- Великолепные истории
- Начинающие авторы
- Современная зарубежная литература
- Боевые искусства
- Изобразительное искусство, фотография
- Кино
- Литература 19 века
- Недвижимость
- Музыка, музыканты
- Готические новеллы
- Истории из жизни
- Культура и искусство
- Спецслужбы
- Зарубежная прикладная литература
- Музыка, танцы
- Подростковая литература
- Прочее
- Военная техника, оружие
- Газеты и журналы
- Периодические издания
- Домоводство, Дом и семья
- Любовные романы
- Экономическая литература
- Научные и научно-популярные книги
- О животных
- Биохимия
- Культурология
- Юриспруденция
- Политика
- Психотерапия
- Языкознание
- Научпоп
- Медицина
- Психология, личное
- Радиотехника
- Филология
- Педагогика
- Образовательная литература
- Деловая литература
- Физика
- Науки: разное
- Химия
- Воспитание детей, педагогика
- Детская психология
- Зарубежная публицистика
- Биология
- Архитектура
- Зарубежная психология
- Науки о космосе
- Социология
- Математика
- География
- Беременность, ожидание детей
- Литературоведение
- Транспорт, военная техника
- Обществознание
- Зоология
- География
- Альтернативная медицина
- Иностранные языки
- Ветеринария
- Рефераты
- Астрология
- Биофизика
- Экология
- История Европы
- Учебники
- Шпаргалки
- Государство и право
- Ботаника
- Религиоведение
- История
- Техническая литература
- Прочая научная литература
- Психология
- Детективы и Триллеры
- Справочная литература
- Проза
- Новелла
- Юмор
- Проза
- Историческая проза
- Русская современная проза
- Советская классическая проза
- Повести
- Очерки
- Эссе
- Рассказы
- Зарубежная современная проза
- Сентиментальная проза
- Зарубежная классика
- Афоризмы
- Эпистолярная проза
- Феерия
- Семейный роман/Семейная сага
- Разное
- Антисоветская литература
- Магический реализм
- Русская классическая проза
- Современная проза
- О войне
- Контркультура
- Классическая проза
- Поэзия, Драматургия
- Детская литература
- Детская фантастика
- Детские остросюжетные
- Детские стихи
- Детские приключения
- Внеклассное чтение
- Учебная литература
- Зарубежные детские книги
- Бизнес
- Загадки
- Книги для подростков
- Школьные учебники
- Детский фольклор
- Книги для дошкольников
- Детские детективы
- Детская познавательная и развивающая литература
- Буквари
- Прочая детская литература
- Сказка
- Детская проза
- Детская образовательная литература
- Юмор
- Документальные книги
- Бизнес
- Внешнеэкономическая деятельность
- Тайм-менеджмент
- Кадровый менеджмент
- О бизнесе популярно
- Управление, подбор персонала
- Бизнес
- Менеджмент и кадры
- Продажи
- Экономика
- Ценные бумаги и инвестиции
- Малый бизнес
- Делопроизводство, офис
- Корпоративная культура, бизнес
- Банковское дело
- Финансы
- Зарубежная деловая литература
- Ораторское искусство / риторика
- Личные финансы
- Интернет-бизнес
- Поиск работы
- Государственное и муниципальное управление
- Бухучет и аудит
- Работа с клиентами
- Менеджмент
- Краткое содержание
- Личная эффективность
- Переговоры
- Приключения
- Старинная литература
- Религия и духовность
- Компьютеры и Интернет
- Блог
Читаем без скачивания ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание - Эндрю Троелсен
Шрифт:
Интервал:
Закладка:
public JamesBondCar(bool skyWorthy, bool seaWorthy) {
canFly = skyWorthy; canSubmerge = seaWorthy;
}
// Для XmlSerializer нужен конструктор, заданный по умолчанию!
public JamesBondCar(){}
…
}
При этом вы сможете сохранить любое число объектов JamesBondCar так.
static void Main(string[] args) {
…
// Сохранение объекта List‹› с набором JamesBondCar.
List‹JamesBondCar› myCars = new List‹JamesBondCar›();
myCars.Add(new JamesBondCar(true, true));
myCars.Add(new JamesBondCar(true, false));
myCars.Add(new JamesBondCar(false, true));
myCars.Add(new JamesBondCar(false, false));
fStream = new FileStream("CarCollection.xml", FileMode.Create, FileAccess.Write, FileShare.None);
xmlFormat = new XmlSerializer(typeof(List‹JamesBondCar›), new Type[] {typeof(JamesBondCar), typeof(Car), typeof(Radio)});
xmlFormat.Serialize(fStream, myCars);
fStream.Close();
Console.ReadLine();
}
Снова обращаем внимание на то, что по причине использования XmlSerializer требуется указать информацию типа для каждого из объектов, вложенных в корневой объект (которым в данном случае является List‹›). При использовании BinaryFormatter или SoapFormatter программная логика будет еще проще.
statiс void Main (string[] args) {
…
// Сохранение объекта List‹›(myCars) в двоичном формате.
list‹JamesBondCar› myCars = new List‹JamesBondCar›();
…
BinaryFormatter binFormat = new BinaryFormatter();
Stream fStream = new FileStream("AllMyCars.dat", FileMode.Create, FileAccess.Write, FileShare.None);
binFormat.Serialize(fStream, myCars);
fStream.Close();
Console.ReadLine();
}
Превосходно! К этому моменту вам должно быть понятно, как использовать сервис сериализации объектов для упрощения процесса сохранения и восстановления данных вашего приложения. Теперь давайте выясним, как использовать пользовательские настройки процесса сериализации.
Исходный код. Проект SimpleSerialize размещен в подкаталоге, соответствующем главе 17.
Настройка процесса сериализации
В большинстве случаев типовая схема сериализации, предлагаемая платформой .NET, будет именно тем, что требуется. Тогда нужно просто применить атрибут [Serializable] и передать объектный граф выбранному средству форматирования. Но в некоторых случаях может потребоваться корректировка того, как обрабатывается объектный граф в процессе сериализации. Например, в соответствии с внутренними правилами вашей компании все поля данных должны сохраняться в формате верхнего регистра или, возможно, вы хотите добавить в поток дополнительные элементы данных, которые не проецируются непосредственно в поля сохраняемого объекта (это могут быть штампы времени, уникальные имена или что-то иное).
Для непосредственного участия в управлении процессом сериализации объектов пространство имен System.Runtime.Serialization предлагает специальные типы. В табл. 17.2 описаны те из них, о которых вам следует знать.
Таблица 17.2. Основные типы пространства имен System.Runtime.Serialization
Тип Описание ISerializable В .NET 1.1 реализация этого интерфейса была наиболее предпочтительным методом пользовательской сериализации объектов. В .NET 2.0 для настройки параметров процесса сериализации предпочтительнее использовать новое множество атрибутов (они будут описаны чуть позже) ObjectIDGenerator Тип, генерирующий идентификаторы элементов объектного графа OnDeserializedAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается сразу же после выполнения реконструкции объекта OnDeserializingAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается в процессе выполнения реконструкции объекта OnSerializedAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается сразу же после выполнения сериализации объекта OnSerializingAttribute Атрибут .NET 2.0, позволяющий указать метод, который вызывается в процессе сериализации OptionalFieldAttribute Атрибут .NET 2.0, позволяющий указать поле типа, которое может отсутствовать в указанном потоке SerializationInfo По сути, этот класс является "чемоданом свойств", содержащим пары имен и значений, представляющих состояние объекта в процессе сериализацииБолее глубокий взгляд на сериализацию объектов
Перед тем как рассмотреть различные способы настройки параметров процесса сериализации, было бы полезно выяснить, что при этом происходит "за кулисами". Когда тип BinaryFormatter выполняет сериализацию объектного графа, этот тип отвечает за передачу в указанный поток следующей информации:
• абсолютных имен объектов графа (например, MyApp.JamesBondCar);
• имени компоновочного блока, определяющего объектный граф (например, MyApp.exe);
• экземпляра класса SerializationInfo, содержащего все данные, поддерживаемые членами объектного графа.
В процессе реконструкции объекта тип BinaryFormatter использует ту же информацию, извлеченную из соответствующего потока, для построения абсолютно точной копии объекта.
Замечание. Напомним, что SoapFormatter и XmlSerializer не сохраняют абсолютное имя типа и имя определяющего компоновочного блока. Эти типы заботятся только о сохранении открытых полей данных.
Общую картину можно представлять в виде диаграммы, показанной на рис. 17.3.
Рис. 17.3 Схема процесса сериализации
Кроме перемещения необходимых данных в поток и извлечения их из потока, средство форматирования (форматтер) анализирует члены объектного графа на наличие следующих элементов инфраструктуры.
• Выясняется, обозначен ли объект атрибутом [Serializable]. Если нет, то генерируется исключение SerializationException.
• Если объект обозначен атрибутом [Serializable], то выясняется, реализует ли объект интерфейс ISerializable. Если да, то для объекта вызывается GetObjectData().
• Если объект не реализует ISerializable, используется типовой процесс сериализации, сохраняются все поля, не обозначенные атрибутом [NonSerialized].
Вдобавок к выявлению поддержки типом интерфейса ISerializable, форматтеры (в .NET 2.0) отвечают также за выявление поддержки соответствующими типами членов, обозначенных атрибутами [OnSerializing], [OnSerialized], [OnDeserializing] или [OnDeserialized]. Роль этих атрибутов будет обсуждаться позже, a пока что мы рассмотрим роль ISerializable.
Настройка параметров сериализации с помощью ISerializable
Объекты, обозначаемые атрибутом [Serializable], имеют возможность реализовать интерфейс ISerializable. В этом случае вы можете "участвовать" в процессе сериализации, выполняя любое предварительное или последующее форматирование данных. Указанный интерфейс очень прост, поскольку он определяет единственный метод, GetObjectData().
// Для настройки процесса сериализации реализуйте ISerializable.
public interface ISerializable {
void GetObjectData(SerializationInfo info, StreamingContext context);
}
Метод GetObjectData() вызывается форматтером в процессе сериализации автоматически. Реализация этого метода предоставляет через входной параметр SerializationInfo серию пар имен и значений, которые (обычно) соответствуют полям данных того объекта, который следует сохранить. Тип SerializationInfo определяет перегруженный метод AddValue(), имеющий множество вариаций, а также небольшой набор свойств, которые позволяют читать и устанавливать имя типа, имя определяющего компоновочного блока и значение счетчика членов. Вот фрагмент соответствующего программного кода.
public sealed class SerializationInfo: object {
public SerializationInfo(Type type, IFormatterConverter converter);
public string AssemblyName { get; set; }
public string FullTypeName { get; set; }
public int MemberCount { get; }
public void AddValue(string name, short value);
public void AddValue(string name, UInt16 value);
public void AddValue(string name, int value);
…
}
Типы, реализующие интерфейс ISerializable, должны также определять специальный конструктор в соответствии со следующим шаблоном.
// Следует предложить пользовательский конструктор следующего вида,
// чтобы среда выполнения могла установить состояние вашего объекта.
[Serializable]
class SomeClass: ISerializable {
private SomeClass(SerializationInfo si, StreamingContext ctx) {…}
…
}
Обратите внимание на то, что для области видимости этого конструктора указано private. Это вполне допустимо, поскольку форматтер получает доступ к этому члену независимо от его видимости. Эти специальные конструкторы чаще всего обозначаются как приватные, чтобы обеспечить невозможность случайного создания объекта пользователем объекта с помощью такого конструктора. Заметьте, что первый параметр этого конструктора является (как и ранее) экземпляром типа SerializationInfo.