XmlSerializer поддерживает ShouldSerialize{Foo}()
шаблон, таким образом, можно добавить метод:
public bool ShouldSerializeID() {return ID.HasValue;}
существует также {Foo}Specified
шаблон - не уверен если поддержки XmlSerializer что один.
Я использую эту микроструктуру для реализации сериализации Nullable:
[XmlIgnore]
public double? SomeValue { get; set; }
[XmlAttribute("SomeValue")] // or [XmlElement("SomeValue")]
[EditorBrowsable(EditorBrowsableState.Never)]
public double XmlSomeValue { get { return SomeValue.Value; } set { SomeValue= value; } }
[EditorBrowsable(EditorBrowsableState.Never)]
public bool XmlSomeValueSpecified { get { return SomeValue.HasValue; } }
Это предоставляет правильный интерфейс пользователю без компромисса и все еще делает правильную вещь при сериализации.
Я выяснил обходное решение, использующее два свойства. Интервал? свойство с атрибутом XmlIgnore и свойством объекта, которое сериализируется.
/// <summary>
/// Score db record
/// </summary>
[System.Xml.Serialization.XmlIgnore()]
public int? ID
{
get
{
return iID_m;
}
set
{
iID_m = value;
}
}
/// <summary>
/// Score db record
/// </summary>
[System.Xml.Serialization.XmlElement("ID",IsNullable = false)]
public object IDValue
{
get
{
return ID;
}
set
{
if (value == null)
{
ID = null;
}
else if (value is int || value is int?)
{
ID = (int)value;
}
else
{
ID = int.Parse(value.ToString());
}
}
}
Ничего себе, спасибо этот вопрос/ответ действительно выручило меня. Я сердечный Stackoverflow.
я сделал то, что Вы делаете выше немного более универсального. Все, что мы действительно ищем, должно иметь Nullable с немного отличающимся поведением сериализации. Я использовал Отражатель для создания моего собственного Nullable и добавил несколько вещей тут и там, чтобы заставить сериализацию XML проложить себе путь, мы хотим. Кажется, работает вполне прилично:
public class Nullable<T>
{
public Nullable(T value)
{
_value = value;
_hasValue = true;
}
public Nullable()
{
_hasValue = false;
}
[XmlText]
public T Value
{
get
{
if (!HasValue)
throw new InvalidOperationException();
return _value;
}
set
{
_value = value;
_hasValue = true;
}
}
[XmlIgnore]
public bool HasValue
{ get { return _hasValue; } }
public T GetValueOrDefault()
{ return _value; }
public T GetValueOrDefault(T i_defaultValue)
{ return HasValue ? _value : i_defaultValue; }
public static explicit operator T(Nullable<T> i_value)
{ return i_value.Value; }
public static implicit operator Nullable<T>(T i_value)
{ return new Nullable<T>(i_value); }
public override bool Equals(object i_other)
{
if (!HasValue)
return (i_other == null);
if (i_other == null)
return false;
return _value.Equals(i_other);
}
public override int GetHashCode()
{
if (!HasValue)
return 0;
return _value.GetHashCode();
}
public override string ToString()
{
if (!HasValue)
return "";
return _value.ToString();
}
bool _hasValue;
T _value;
}
Вы теряете способность иметь Ваших участников как интервал? и так далее (должны использовать Nullable< int> вместо этого), но кроме которого остается таким же все поведение.
К сожалению, поведения, которые Вы описываете, точно документируются как таковые в документах для XmlElementAttribute. IsNullable.