Атрибуты 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.
Есть ли у кого-нибудь идеи, как я могу это сделать?
Спасибо.
Ответы
Ответ 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;
}
}