Разработка приложений на языке C#. Полезные настройки. Особые спецификаторы формата, страница 37

             new Address ("Ron Nox", "New York", "NY"),

             new Address ("Ton Rox", null, "CA")

          };

  XmlSerializer serializer =  new XmlSerializer (typeof(Address[]));

  TextWriter sw = new StreamWriter ("../../Address.xml");

  serializer.Serialize (sw, addr);

  sw.Close();

  Console.WriteLine("\n\t\tPress any key to go to main menu\n");

  Console.ReadKey(true);

}

}

Обратите внимание на тип аргумента typeof(Address[]) при вызове конструктора класса XmlSerializer. Если бы надо было сохранить только один объект класса Address, то аргумент должен был быть typeof(Address). Опробуйте этот прием, затем откройте файл Address.xml и рассмотрите различия в структуре элементов. Обратите внимание на атрибут name (не элемент, а атрибут). Чтение файла Address.xml может быть призведено с помощью метода Deserialize.

FileStream fs = new FileStream("../../Address.xml", FileMode.Open);

Address[] newAddr = (Address[]) serializer.Deserialize (fs);

fs.Close();

foreach (Address a in newAddr) // Проверка

  Console.WriteLine (a);

Для того, чтобы с помощью XmlSerializer сохранить динамическую коллекцию (ArrayList) объектов типа Address можно поступить следующим образом.

·  Создать класс, инкапсулирующий коллекцию, например, MyList.

·  Поместить в класс коллекцию ArrayList и пометить ее атрибутом [XmlElement(typeof(Address))].

·  Создать объект класса XmlSerializer, настроив его на тип данных MyList,

·  Работать с объектами типов MyList и XmlSerializer обычным образом.

public class MyList

{

[XmlElement(typeof(Address))]

public ArrayList addrs;

public MyList () { addrs = new ArrayList(); }

public void Add (Address a) { addrs.Add(a); }

}

public class Program

{

public static void TestArrayListOfAddress()

{

  MyList list = new MyList();

  list.Add (new Address ("Don Box", "Redmont", "WA"));

  list.Add (new Address ("Ron Nox", "New York", "NY"));

  list.Add (new Address ("Ton Rox", null, "CA"));

  XmlSerializer serializer = new XmlSerializer (typeof(MyList));

  TextWriter sw = new StreamWriter ("../../Address.xml");

  serializer.Serialize (sw, list);

  sw.Close();

}

}

Ниже показано, как прочесть коллекцию. При этом подразумевается, что serializer уже настроен на тип MyList.

FileStream fs = new FileStream("../../Address.xml", FileMode.Open);

MyList newList = (MyList) serializer.Deserialize (fs);

foreach (Address a in newList.addrs)

  Console.WriteLine (a);

fs.Close();

Наконец, покажем, как работать с гетерогенной коллекцией объектов. Предположим, что мы хотим сериализовать тот список полиморфных объектов (Stud и Prof), который был разработан выше. Для этой цели нам придется (при объявлении сериализуемой сущности) воспользоваться услугами более сложного атрибута:

[XmlElement(typeof(Stud)), XmlElement(typeof(Prof))]

public ArrayList men; // Список ссылок на объекты из иерархии Man

Важным условием работы алгоритма является то, что сам список (объект men класса ArrayList) должен быть доступен serializer'у. Не забудьте заменить спецификатор доступа объекта men (в классе List). Сделайте его public. Теперь схема работы с объектами напоминает предыдущий вариант.

public static void TestXmlSerializerHetero ()

{

  List list = new List();

  list.Work(); // Здесь следует прочесть список в нашем (текстовом) формате с помощью метода List.Read

   //=== Теперь создадим XmlSerializer для записи гетерогенного списка в формате XML

  XmlSerializer serializer = new XmlSerializer (typeof(List));

  TextWriter sw = new StreamWriter ("../../List.xml");

  serializer.Serialize (sw, list);

  sw.Close();

  list.men.Clear();  // Не откладывая, убедимся, что все работает

  FileStream fs = new FileStream("../../List.xml", FileMode.Open);

  list = (List) serializer.Deserialize (fs);

  list.Show();

}