Читать «ЯЗЫК ПРОГРАММИРОВАНИЯ С# 2005 И ПЛАТФОРМА .NET 2.0. 3-е издание» онлайн - страница 405
Эндрю Троелсен
‹JamesBondCar xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema" canFly="true" canSubmerge="false"
xmlns="http://www.intertechtraining.com"›
…
‹/JamesBondCar›"
Конечно, есть множество других атрибутов, которые вы можете использовать для управления процессом генерирования XML-документа с помощью XmlSerializer. Чтобы ознакомиться со всеми опциями, выполните поиск информации о пространстве имен System.Xml.Serialization в документации .NET Framework 2.0 SDK
Сохранение коллекций объектов
Теперь вы знаете, как сохранить в потоке отдельный объект, и давайте выясним, как сохранить множество объектов. Заметим, что метод Serialize() интерфейса IFormatter не позволяет указать произвольное число объектов (а только один System.Object). Аналогично, возвращаемым значением Deserialize() тоже является один System.Object.
public interface IFormatter {
…
object Deserialize(System.IO.Stream serializationStream);
void Serialize(System.IO.Stream serializationStream, object graph);
}
Напомним, что System.Object фактически представляет весь объектный граф. Поэтому при передаче объекта, обозначенного атрибутом [Serializable] и содержащего другие объекты [Serializable], будет сохранен сразу весь набор объектов. Большинство типов, находящихся в рамках пространства имен System.Collections и System.Collections.Generic, уже обозначены атрибутом [Serializable]. Таким образом, чтобы сохранить набор объектов, просто добавьте этот набор в контейнер (например, в ArrayList или List‹›) и выполните сериализацию полученного объекта в подходящий поток.
Предположим, что в класс JamesBondCar был добавлен конструктор с двумя аргументами, чтобы можно было установить некоторые начальные данные состояния (обратите внимание на то, что конструктор, заданный по умолчанию, был возвращен на место в соответствии с требованиями XmlSerializer),
[Serializable,
XmlRoot(Namespace = "http://www.intartechtraining.com")]
public class JamesBondCar: Car {
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 программная логика будет еще проще.