1/9/2008 3:52:00 PM

Некоторые классы .NET Framework ведут себя при сериализации с помощью XmlSerializer достаточно странно. Некоторые не сериализуются вообще, некоторые, например тот же System.Drawing.Color, сериализуют только поле, но игнорируют его значение. То есть, сериализация объекта со свойством:

[XmlElement("backgroundColor")]
public Color BgColor
{
    get { return _bgColor; }
    set { _bgColor = value; }
}

приведет к тому, что будет сериализована пустая нода <backgroundColor />, значение же сериализоваться не будет, как бы мы его не присваивали.
К слову, этого я вообще не понимаю. Ну не умеешь ты сериализовать класс - ну выкинь ты исключение, зачем такую ерунду делать... Впрочем, если же возникнет желание сериализовать цвет xml-атрибутом, то, действительно, получится исключение.
Но не об этом речь.

Иногда все же нужно сериализовать несериализуемое, а делать для этого в классах дополнительные свойства, которые будут использоваться только для сериализации (например, можно было бы сделать string StringBgColor, пометить его как Browsable(false), чтобы его никто не видел, а само свойство Color BgColor поменить как XmlIgnore).
Но этот подход мне не нравится, так как в интерфейсе объекта плодятся ненужные свойства, которые, в общем-то, логически дублируют друг друга.

На мой взгляд грамотнее написать свой тип Color точнее, "обертку" для него (назовем ее XmlColor), которая с одной стороны будет нормально сериализоваться, с другой стороны будет "прозрачной" для использования совместно со "стандартным" Color.
То есть, чтобы можно было написать Color myColor = myXmlColor и наоборот, а приведение типов производилось бы автоматически. Тогда введение нового типа никак не будет мешать ни логике работы программы, ни разработчикам.

Вот пример такого типа:

public struct XmlColor : System.Xml.Serialization.IXmlSerializable
{
    private Color _color;

    public XmlColor(Color c)
    {
        _color = c;
    }

    public Color Color
    {
        get { return _color; }
    }

    public static implicit operator Color(XmlColor c)
    {
        return c.Color;
    }

    public static implicit operator XmlColor(Color c)
    {
        return new XmlColor(c);
    }

    System.Xml.Schema.XmlSchema IXmlSerializable.GetSchema()
    {
        return null;
    }

    void IXmlSerializable.ReadXml(System.Xml.XmlReader reader)
    {
        _color = ColorTranslator.FromHtml(reader.ReadString());
    }

    void IXmlSerializable.WriteXml(System.Xml.XmlWriter writer)
    {
        writer.WriteString(ColorTranslator.ToHtml(this.Color));
    }
}

Он инкапсулирует в себе "нормальный" Color, "умеет" приводиться к нему и из него, а так же может быть сериализован в качестве xml-элемента. Естественно, вместе со значением :) Таким образом, вместо свойства Color BgColor {get; set;} мы сможем определить свойство XmlColor BgColor {get; set;} и все будет работать так, как планировалось, а благодаря возможности неявного приведения замена одного типа другим пройдет незаметно и безболезненно.

P.S. К слову сказать, реализация IXmlSerializable может быть полезна и в некоторых других случаях. Например, если свойства класса хранят некоторую информацию, которая должна быть доступна в этих свойствах в момент работы приложения, но должна быть сериализована в зашифрованном виде...

Comments (3) -

1/13/2008 6:38:08 AM

romken

ну да, сам пользуюсь этим методом...пожалуй это самое эффективное средство

romken Russia

3/19/2008 9:49:58 AM

Антон

Спасибо, сериализуется нормально.
Только почему-то при десериализации, если класс содержит несколько таких XmlColor, читается только один из них (a):

public class TestClass
{
    XmlColor a;
    XmlColor b;
    XmlColor c;
}

Где ошибка?

Антон

3/24/2008 4:02:29 PM

Alexey Raga

Честно говоря навскидку не скажу - надо пробовать.
Мне десериализация не требовалась Smile

Alexey Raga

Comments are closed

Powered by BlogEngine.NET 2.5.0.6

About the author

Alexey Raga Alexey Raga
.NET software developer.

E-mail me Send mail

Twitter


Recent posts

Archive

Disclaimer

The opinions expressed herein are my own personal opinions and do not represent my employer's view in anyway.

© Copyright 2012

Sign in