null 가능한 int 직렬화
nullable int? data type이 xml 요소로 serialize되도록 설정된 클래스가 있습니다.값이 null일 경우 xml serializer가 요소를 serialize하지 않도록 설정할 방법이 있습니까?
[시스템]을 추가하려고 했습니다.Xml. serialization.XmlElement(IsNullable=falsefalse)] 특성이지만 "IsNullable이 Nullable 유형에 대해 'nullable'로 설정되지 않을 수 있으므로 해당 유형을 반영하는 오류가 있다는 런타임 직렬화 예외가 발생합니다.'시스템' 사용을 고려합니다.Int32'를 입력하거나 XmlElement 특성에서 IsNullable 속성을 제거합니다."
[Serializable]
[System.Xml.Serialization.XmlRoot("Score", Namespace = "http://mycomp.com/test/score/v1")]
public class Score
{
private int? iID_m;
...
/// <summary>
///
/// </summary>
public int? ID
{
get
{
return iID_m;
}
set
{
iID_m = value;
}
}
...
}
위 클래스는 다음으로 직렬화됩니다.
<Score xmlns="http://mycomp.com/test/score/v1">
<ID xsi:nil="true" />
</Score>
그러나 null인 ID의 경우 ID 요소를 전혀 원하지 않습니다. 주로 MSSQL에서 OPENXML을 사용할 때 다음과 같이 보이는 요소에 대해 null이 아닌 0을 반환하기 때문입니다.
XmlSerializer는ShouldSerialize{Foo}()method를 추가할 수 있도록 pattern(패턴):
public bool ShouldSerializeID() {return ID.HasValue;}
또한 있습니다.{Foo}Specifiedpattern - XmlSerializer가 이를 지원하는지 확실하지 않습니다.
이 마이크로 패턴을 사용하여 Nullable serialization을 구현합니다.
[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 특성과 직렬화되는 개체 속성을 가진 int? 속성입니다.
/// <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());
}
}
}
와우 감사합니다 이 질문/답변이 정말 도움이 되었습니다.스택 오버플로.
위에서 하시는 일을 좀 더 일반적으로 만들었습니다.우리가 정말로 원하는 것은 조금 다른 직렬화 동작을 가진 Nullable을 갖는 것입니다.Reflector를 사용하여 나만의 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;
}
구성원을 int? 등으로 사용할 수 있는 기능을 잃게 되지만(대신 Nullable<int>를 사용해야 함), 그 외의 모든 동작은 동일하게 유지됩니다.
안타깝게도 XmlElementAttribute에 대한 문서에 설명된 동작이 정확하게 문서화되어 있습니다.무효입니다.
매우 유용한 포스팅이 많은 도움이 되었습니다.
Scott의 Nullable(Of T) 데이터 유형에 대한 개정판을 선택했지만, 게시된 코드는 Null일 때 Nullable 요소를 직렬화합니다. 비록 "null:fault='true' 속성은 없지만.
serializer가 태그를 완전히 삭제하도록 강제해야 했기 때문에 구조물에 IXmlSerializable을 구현했습니다(이것은 VB에 있지만 그림은 알 수 있습니다).
'----------------------------------------------------------------------------
' GetSchema
'----------------------------------------------------------------------------
Public Function GetSchema() As System.Xml.Schema.XmlSchema Implements System.Xml.Serialization.IXmlSerializable.GetSchema
Return Nothing
End Function
'----------------------------------------------------------------------------
' ReadXml
'----------------------------------------------------------------------------
Public Sub ReadXml(ByVal reader As System.Xml.XmlReader) Implements System.Xml.Serialization.IXmlSerializable.ReadXml
If (Not reader.IsEmptyElement) Then
If (reader.Read AndAlso reader.NodeType = System.Xml.XmlNodeType.Text) Then
Me._value = reader.ReadContentAs(GetType(T), Nothing)
End If
End If
End Sub
'----------------------------------------------------------------------------
' WriteXml
'----------------------------------------------------------------------------
Public Sub WriteXml(ByVal writer As System.Xml.XmlWriter) Implements System.Xml.Serialization.IXmlSerializable.WriteXml
If (_hasValue) Then
writer.WriteValue(Me.Value)
End If
End Sub
객체에 중복 속성의 버킷 로드를 추가해야 하는 (foo)Specified 패턴을 사용하는 것보다 이 방법을 선호합니다. 반면 새 Nullable 유형을 사용하는 경우 속성을 다시 입력해야 합니다.
[XmlIgnore]
public int? Revision { get; set; }
[XmlAttribute("Revision")]
public string RevisionAsString
{
get => Revision?.ToString();
set => Revision = string.IsNullOrEmpty(value) ? default : int.Parse(value);
}
public bool ShouldSerializeRevisionAsString()
{
return Revision.HasValue;
}
언급URL : https://stackoverflow.com/questions/244953/serialize-a-nullable-int
'programing' 카테고리의 다른 글
| 구글 크롬으로 커스텀 URL 스킴을 오픈할 수 있습니까? (0) | 2023.09.14 |
|---|---|
| Excel 관리도 x축에서 날짜-시계열을 허용하지 않음 (0) | 2023.09.14 |
| Ubuntu의 Oracle XE에서 새 데이터베이스 생성 (0) | 2023.09.14 |
| python을 사용하여 excel로 작업하는 중 오류 발생 (0) | 2023.09.14 |
| jQuery 또는 페이지의 메모리 사용량을 찾기 위한 javascript (0) | 2023.09.09 |