private Product[] stuff;
public Inventory() {}
Мы имеем XmlArrayItem
для каждого типа, который может быть добавлен в массив. Первый параметр определяет имя элемента в создаваемом документе XML. Если опустить этот параметр ElementName
, то элементы получат имя типа объекта (в данном случае Product
и BookProduct
). Существует также класс XmlArrayAttribute
, который будет использоваться, если свойство возвращает массив объектов или примитивных типов. Так как мы возвращаем в массиве различные типы, то используется объект XmlArrayItemAttribute
, который предоставляет более высокий уровень управления:
// необходимо иметь запись атрибута для каждого типа данных
[XmlArrayItem('Prod', typeof(Product)), XmlArrayItem('Book', typeof(BookProduct))]
//public Inventory(Product [] InventoryItems) {
// stuff=InventoryItems;
//}
public Product[] InventoryItems {
get {return stuff;}
set {stuff=value;}
}
}
//класс Product
public class Product {
private int prodId;
private string prodName;
private int suppId;
public Product() {}
public int ProductID {
get {return prodId;}
set {prodId=value;}
}
public string ProductName {
get {return prodName;}
set {prodName=value;}
}
public int SupplierID {
get {return suppId;}
set {suppId=value;}
}
}
// Класс Bookproduct
public class BookProduct: Product {
private string isbnNum;
public BookProduct() {}
public string ISBN {
get {return isbnNum;}
set {isbnNum=value;}
}
}
В этот пример добавлено два новых класса. Класс Inventory
будет отслеживать то, что добавляется на склад. Можно добавлять продукцию на основе класса Product
или класса BookProduct
, который расширяет Product
. В классе Inventory
содержится массив добавленных объектов и в нем могут находиться как BookProducts
, так и Products
. Вот как выглядит документ XML:
<?xml version='1.0' ?>
<Inventory xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xmlns:xsd='http://www.w3.org/2001/XMLSchema'>
<InventoryItems>
<Prod>
<ProductID>100</ProductID>
<ProductName>Product Thing</ProductName>
<SupplierID>10</SupplierID>
</Prod>
<Book>
<ProductID>101</ProductID>
<ProductName>How to Use Your New Product Thing</ProductName>
<SupplierID>10</SupplierID>
<ISBN>123456789</ISBN>
</Book>
</InventoryItems>
</Inventory>
Все это работает прекрасно, но как быть в ситуации, когда нет доступа к исходному коду типов, которые будут сериализироваться? Невозможно добавить атрибут, если отсутствует исходный код. Существует другой способ. Можно воспользоваться классами XmlAttributes
и XmlAtrtributeOverrides
. Вместе эти классы позволят выполнить в точности то, что только что было сделано, но без добавления атрибутов. Вот пример, находящийся в папке SerialSample4
:
private void button1_Click(object sender, System.EventArgs e) {
// создать объект XmlAttributes XmlAttributes attrs=new XmlAttributes();
// добавить типы объектов, которые будут сериализированы
attrs.XmlElements.Add(new XmlElementAttribute('Book', typeof(BookProduct)));
attrs.XmlElements.Add(new XmlElementAttribute('Product', typeof(Product)));
XmlAttributeOverrides attrOver=new XmlAttributeOverrides();
//добавить к коллекций атрибутов
attrOver.Add(typeof(Inventory), 'InventoryItems', attrs);
// создать объекты Product и Book
Product newProd=new Product();
BookProduct newBook=new BookProduct();
newProd.ProductID=100;
newProd.ProductName='Product Thing';
newProd.SupplierID=10;
newBook.ProductID=101;
newBook.ProductName='How to Use Your New Product Thing';
newBook.SupplierID=10;
newBook.ISBN='123456789';
Product[] addProd={newProd, newBook};
//Product[] addProd={newBook};