Чтение онлайн

на главную - закладки

Жанры

Интернет-журнал "Домашняя лаборатория", 2007 №9
Шрифт:

Если класс объявить с атрибутом [Serializable], то в него встраивается стандартный механизм сериализации, поддерживающий, что крайне приятно, глубокую сериализацию. Если по каким-либо причинам стандартная сериализация нас не устраивает, то класс следует объявить наследником интерфейса ISseriaizabie, реализация методов которого позволит управлять процессом сериализации. Мы рассмотрим обе эти возможности.

Класс с атрибутом сериализации

Класс, объекты которого предполагается сериализовать стандартным образом, должен при объявлении сопровождаться атрибутом [Serializable]. Стандартная

сериализация предполагает два способа сохранения объекта: в виде бинарного потока символов и в виде xml-документа. В бинарном потоке сохраняются все поля объекта, как открытые, так и закрытые. Процессом этим можно управлять, помечая некоторые поля класса атрибутом [Nonserialized] — эти поля сохраняться не будут:

[Serializable] public class Test

{

public string name;

[NonSerialized] int id; int age;

//другие поля и методы класса

}

В класс Test встроен стандартный механизм сериализации его объектов. При сериализации поля name и аде будут сохраняться, поле id — нет.

Для запуска механизма необходимо создать объект, называемый форматером и выполняющий сериализацию и десериализацию данных с подходящим их форматированием. Библиотека FCL предоставляет два класса форматеров. Бинарный форматер, направляющий данные в бинарный поток, принадлежит классу BinaryFormatter. Этот класс находится в пространстве имен библиотеки FCL:

System.Runtime.Serialization.Formatters.Binary

Давайте разберемся, как устроен этот класс. Он является наследником двух интерфейсов: iFormatter и IRemotingFormatter. Интерфейс IFormatter имеет два открытых метода: Serialize и Deserialize, позволяющих сохранять и восстанавливать всю совокупность связанных объектов с заданным объектом В качестве корня. Интерфейс IRemotingFormatter имеет те же открытые методы: Serialize и Deserialize, позволяющие выполнять глубокую сериализацию, но в режиме удаленного вызова. Поскольку сигнатуры одноименных методов интерфейсов отличаются, то конфликта имен при наследовании не происходит — В классе BinaryFormatter методы Serialize и Deserialize перегружены. Для удаленного вызова задается дополнительный параметр, что и позволяет различать, локально или удаленно выполняются процессы обмена данными.

В пространстве имен библиотеки FCL:

System.Runtime.Serialization.Formatters.Soap

находится класс SoapFormatter. Он является наследником тех же интерфейсов IFormatter и IRemotingFormatter и реализует их методы Serialize и Deserialize, позволяющие выполнять глубокую сериализацию и десериализацию при сохранении данных в формате xml. Помимо методов класса SoapFormatter, xml-сериализацию можно выполнять средствами другого класса — XmlSerializer.

Из новых средств, еще не рассматривавшихся в наших лекциях, для организации сериализации понадобятся файлы. Пространство имен ю библиотеки FCL предоставляет классы, поддерживающие ввод-вывод данных. В частности, в этом пространстве

есть абстрактный класс Stream для работы с потоками данных. С одним из его потомков — классом FileStream — мы и будем работать в нашем примере.

В качестве примера промоделируем сказку Пушкина "О рыбаке и рыбке". Как вы помните, жадная старуха богатела, богатела, но после очередного желания оказалась у разбитого корыта, вернувшись в начальное состояние. Сериализация позволит нам запомнить начальное состояние, меняющееся по мере выполнения рыбкой первых пожеланий рыбака и его старухи. Десериализация вернет все в начальное состояние. Опишу класс, задающий героев пушкинской сказки:

[Serializable]

public class Personage

{

public Personage(string name, int age)

{

this.name = name; this.age = age;

}

//поля класса static int wishes;

public string name, status, wealth; int age;

public Personage couple;

//методы класса

}

Герои сказки — объекты этого класса обладают свойствами, задающими имя, возраст, статус, имущество и супруга. Имя и возраст задаются в конструкторе класса, а остальные свойства задаются в следующем методе:

public void marry (Personage couple)

{

this.couple = couple;

couple.couple = this;

this.status ="крестьянин";

this.wealth ="рыбацкая сеть";

this.couple.status = "крестьянка";

this.couple.wealth = "корыто";

SaveState ;

}

Предусловие метода предполагает, что метод вызывается один раз главным героем (рыбаком). В методе устанавливаются взаимные ссылки между героями сказки, их начальное состояние. Завершается метод сохранением состояния объектов, выполняемого при вызове метода SaveState:

void SaveState

{

BinaryFormatter bf = new BinaryFormatter ;

FileStream fs = new FileStream

("State.bin",FileMode.Create, FileAccess.Write);

bf.Serialize(fs,this);

fs.Close ;

}

Здесь и выполняется сериализация графа объектов. Как видите, все просто. Вначале создается форматер — объект bf класса BinaryFormatter. Затем определяется файл, в котором будет сохраняться состояние объектов, — объект fs класса FileStream. Заметьте, в конструкторе файла, кроме имени файла, указываются его характеристики: статус, режим доступа. На деталях введения файлов я останавливаться не буду. Теперь, когда основные объекты определены, остается вызвать метод Serialize объекта bf, которому в качестве аргументов передается объект fs и текущий объект, представляющий корневой объект графа объектов, которые подлежат сериализации. Глубокая сериализация, реализуемая в данном случае, не потребовала от нас никаких усилий.

Нам понадобится еще метод, описывающий жизнь героев сказки:

public Personage AskGoldFish

{

Personage fisher = this;

if (fisher.name == "рыбак")

{

wishes++;

switch (wishes)

{

case 1: ChangeStateOne;break;

case 2: ChangeStateTwo;break;

case 3: ChangeStateThree;break;

default: BackState(ref fisher);break;

}

}

return(fisher);

}//AskGoldFish

Метод реализует анализ желаний героини сказки. Первые три желания исполняются, и состояние героев меняется:

Поделиться:
Популярные книги

Боксер 2: назад в СССР

Гуров Валерий Александрович
2. Боксер
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Боксер 2: назад в СССР

Гром над Тверью

Машуков Тимур
1. Гром над миром
Фантастика:
боевая фантастика
5.89
рейтинг книги
Гром над Тверью

Безымянный раб [Другая редакция]

Зыков Виталий Валерьевич
1. Дорога домой
Фантастика:
боевая фантастика
9.41
рейтинг книги
Безымянный раб [Другая редакция]

Виконт. Книга 2. Обретение силы

Юллем Евгений
2. Псевдоним `Испанец`
Фантастика:
боевая фантастика
попаданцы
рпг
7.10
рейтинг книги
Виконт. Книга 2. Обретение силы

Титан империи 2

Артемов Александр Александрович
2. Титан Империи
Фантастика:
фэнтези
боевая фантастика
аниме
5.00
рейтинг книги
Титан империи 2

Чиновникъ Особых поручений

Кулаков Алексей Иванович
6. Александр Агренев
Фантастика:
попаданцы
альтернативная история
5.00
рейтинг книги
Чиновникъ Особых поручений

Чужая дочь

Зика Натаэль
Любовные романы:
любовно-фантастические романы
5.00
рейтинг книги
Чужая дочь

Измена. Мой заклятый дракон

Марлин Юлия
Любовные романы:
любовно-фантастические романы
7.50
рейтинг книги
Измена. Мой заклятый дракон

Темный Лекарь 5

Токсик Саша
5. Темный Лекарь
Фантастика:
фэнтези
аниме
5.00
рейтинг книги
Темный Лекарь 5

Барон нарушает правила

Ренгач Евгений
3. Закон сильного
Фантастика:
фэнтези
попаданцы
аниме
5.00
рейтинг книги
Барон нарушает правила

Польская партия

Ланцов Михаил Алексеевич
3. Фрунзе
Фантастика:
попаданцы
альтернативная история
5.25
рейтинг книги
Польская партия

Книга пятая: Древний

Злобин Михаил
5. О чем молчат могилы
Фантастика:
фэнтези
городское фэнтези
мистика
7.68
рейтинг книги
Книга пятая: Древний

Наследница Драконов

Суббота Светлана
2. Наследница Драконов
Любовные романы:
современные любовные романы
любовно-фантастические романы
6.81
рейтинг книги
Наследница Драконов

Адепт: Обучение. Каникулы [СИ]

Бубела Олег Николаевич
6. Совсем не герой
Фантастика:
фэнтези
попаданцы
9.15
рейтинг книги
Адепт: Обучение. Каникулы [СИ]