Подтвердить что ты не робот

Атрибуты XmlSerializer и nullable

У меня есть класс с многочисленными Nullable <T> свойства, которые я хочу сериализовать в XML как атрибуты. Это, по-видимому, нет-нет, поскольку они считаются "сложными типами". Таким образом, вместо этого я реализую шаблон * Specified, где я создаю добавление * Значение и * Указанное свойство следующим образом:

[XmlIgnore]
public int? Age
{
    get { return this.age; }
    set { this.age = value; }
}

[XmlAttribute("Age")]
public int AgeValue
{
    get { return this.age.Value; }
    set { this.age = value; }
}

[XmlIgnore]
public bool AgeValueSpecified
{
    get { return this.age.HasValue; }
}

Что хорошо работает - если свойство "Возраст" имеет значение, оно сериализуется как атрибут. Если он не имеет значения, он не сериализуется.

Проблема в том, что, как я уже упоминал, у меня много Nullable-s в моем классе, и этот шаблон просто делает вещи беспорядочными и неуправляемыми.

Я надеюсь, что есть способ сделать Nullable более удобным для XmlSerializer. Или, в противном случае, способ создать замену Nullable.

Есть ли у кого-нибудь идеи, как я могу это сделать?

Спасибо.

4b9b3361

Ответ 1

Внедрите интерфейс IXmlSerializable в свой класс. Затем вы можете обрабатывать специальные случаи, такие как nullables в методах ReadXML и WriteXML. Хороший пример на странице документации MSDN.

 
class YourClass : IXmlSerializable
{
    public int? Age
    {
        get { return this.age; }
        set { this.age = value; }
    }

    //OTHER CLASS STUFF//

    #region IXmlSerializable members
    public void WriteXml (XmlWriter writer)
    {
        if( Age != null )
        {
            writer.WriteValue( Age )
        }
    }

    public void ReadXml (XmlReader reader)
    {
        Age = reader.ReadValue();
    }

    public XmlSchema GetSchema()
    {
        return(null);
    }
    #endregion
}

Ответ 2

У меня была аналогичная проблема с некоторым кодом, над которым я работал, и я решил просто использовать строку для свойства, которое я сериализовал и десериализовал. У меня получилось что-то вроде этого:

[XmlAttribute("Age")]
public string Age
{
    get 
    { 
        if (this.age.HasValue)
            return this.age.Value.ToString(); 
        else
            return null;
    }
    set 
    { 
        if (value != null)
            this.age = int.Parse(value);
        else
            this.age = null;
    }
}