пятница, 5 августа 2011 г.

Сериализация на C#

Сериализацию (и десериализацию) объекта в .NET можно осуществить двумя способами. Один более универсальный, другой более удобный.

Сначала рассмотрим более удобный способ. С помощью него объект можно сериализовать только в XML.

Первое что нужно для этого сделать -- добавить в References ссылки на System.Xml.dll и (только в Silverlight приложениях) System.Xml.Serialization.dll. В первой, в неймспейсе System.Xml.Serialization содержатся атрибуты, необходимые для указания какому элементу XML соответствует какой-либо класс или свойство:
  • XmlRootAttribute -- указывает на то, что класс к которому он (атрибут) применен, является корнем XML-файла. Он может принимать аргумент ElementName, который задает как будет называться соответствующий тег в XML'е. Если ElementName не задан, то за название тега принимается имя класса, к которому был применен атрибут.
  • XmlAttributeAttribute -- указывает сериализатору на то, что свойство к которому применен атрибут, является атрибутом XML. В качестве аргумента может принимать название атрибута в XML.
  • XmlElementAttribute -- указывает сериализатору на то, что свойство к которому применен атрибут, является элементом XML. Также как и предыдущий может принимать имя в XML в качестве аргумента.
  • XmlArrayAttribute -- применяется к свойству, имеющему перечислимый тип (массив), в случае если необходимо чтобы входящие в соответствующий ему элементы XML дочерние элементы, были представлены как элементы массива этого свойства.
  • XmlArrayItemAttribute -- также применяется к свойству, имеющему перечислимый тип, вместе с атрибутом XmlArrayAttribute, чтобы указать параметры соответствующего элементу массива, элемента XML (например тип или имя).

Пример разметки классов для сериализации приведен в листинге:
using System;
using System.Xml.Serialization;
using System.IO;
namespace SerializationTest1
{
    public class Product
    {
        private string name;
        private int price;
        [XmlElement("price")]
        public int Price
        {
            get { return price; }
            set { price = value; }
        }
        [XmlAttribute("name")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }

    }
    [XmlRoot("shop")]
    public class Shop
    {
        private string owner;
        private string name;
        private Product[] products;
        [XmlAttribute("name")]
        public string Name
        {
            get { return name; }
            set { name = value; }
        }
        [XmlAttribute("owner")]
        public string Owner
        {
            get { return owner; }
            set { owner = value; }
        }
        [XmlArray("products"), XmlArrayItem("product")]
        public Product[] Products
        {
            get { return products; }
            set { products = value; }
        }

    }
}
После разметки сериализуемых классов атрибутами (чтобы сериализатор знал что во что сериализировать), переходим непосредственно к самой сериализации.
Для этого в неймспейсе System.Xml.Serialization существует класс XmlSerializer. Его конструктор принимает в качестве параметра тип класса, который соответствует корневому элементу XML.
Класс содержит 3 нужные нам метода:
CanDeserialize(XmlReader xmlReader) -- проверяет, получится ли получить из переданного в параметре XML, указанный при инстанцировании тип.
Deserialize(XmlReader xmlReader) -- возвращает объект, полученный в результате десериализачии XML считанного из xmlReader.
Serialize(XmlWriter xmlWriter, object o) -- сериализует объект o и записывает полученный XML в xmlWriter.
Пример получения из XML объекта описанного выше класса, приведен в листинге ниже:
using System;
using System.Xml.Serialization;
using System.IO;
namespace SerializationTest1
{
    class Program
    {
        static void Main(string[] args)
        {
            string xml = @"<shop name=""Supershop"" 
                owner=""Fedya Pupkin"">
    <products>
        <product name=""phone"">
            <price>10000</price>
        </product>
        <product name=""book"">
            <price>500</price>
        </product>
    </products>
</shop>";
            XmlSerializer serializer = 
                new XmlSerializer(typeof(Shop));
            object obj = serializer.Deserialize(
                new StringReader(xml));
            Shop shop = (Shop)obj;
        }
    }
}

Комментариев нет:

Отправить комментарий