joe*_*n66 200 c# serialization timespan
我试图将.NET TimeSpan
对象序列化为XML,但它无法正常工作.一个快速谷歌建议,虽然TimeSpan
是可序列化的,但XmlCustomFormatter
它不提供将TimeSpan
对象转换为XML或从XML 转换对象的方法.
一种建议的方法是忽略TimeSpan
序列化,而是序列化结果TimeSpan.Ticks
(并new TimeSpan(ticks)
用于反序列化).一个例子如下:
[Serializable]
public class MyClass
{
// Local Variable
private TimeSpan m_TimeSinceLastEvent;
// Public Property - XmlIgnore as it doesn't serialize anyway
[XmlIgnore]
public TimeSpan TimeSinceLastEvent
{
get { return m_TimeSinceLastEvent; }
set { m_TimeSinceLastEvent = value; }
}
// Pretend property for serialization
[XmlElement("TimeSinceLastEvent")]
public long TimeSinceLastEventTicks
{
get { return m_TimeSinceLastEvent.Ticks; }
set { m_TimeSinceLastEvent = new TimeSpan(value); }
}
}
Run Code Online (Sandbox Code Playgroud)
虽然这似乎适用于我的简短测试 - 这是实现这一目标的最佳方法吗?
有没有更好的方法将TimeSpan序列化为XML?
Ror*_*eod 98
这只是对问题中建议的方法稍作修改,但此Microsoft Connect问题建议使用属性进行序列化,如下所示:
[XmlIgnore]
public TimeSpan TimeSinceLastEvent
{
get { return m_TimeSinceLastEvent; }
set { m_TimeSinceLastEvent = value; }
}
// XmlSerializer does not support TimeSpan, so use this property for
// serialization instead.
[Browsable(false)]
[XmlElement(DataType="duration", ElementName="TimeSinceLastEvent")]
public string TimeSinceLastEventString
{
get
{
return XmlConvert.ToString(TimeSinceLastEvent);
}
set
{
TimeSinceLastEvent = string.IsNullOrEmpty(value) ?
TimeSpan.Zero : XmlConvert.ToTimeSpan(value);
}
}
Run Code Online (Sandbox Code Playgroud)
这会将时间范围0:02:45序列化为:
<TimeSinceLastEvent>PT2M45S</TimeSinceLastEvent>
Run Code Online (Sandbox Code Playgroud)
或者,DataContractSerializer
支持TimeSpan.
Mar*_*ell 69
你已经发布的方式可能是最干净的.如果你不喜欢额外的财产,你可以实施IXmlSerializable
,但是你必须做所有事情,这在很大程度上违背了这一点.我很乐意使用你发布的方法; 它(例如)有效(没有复杂的解析等),文化独立,明确,并且时间戳类型的数字易于和通常被理解.
顺便说一句,我经常补充说:
[Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
Run Code Online (Sandbox Code Playgroud)
这只是隐藏在UI和引用dll中,以避免混淆.
Wes*_*Wes 28
在某些情况下可以使用的是为您的公共属性提供一个支持字段,即TimeSpan,但公共属性是作为字符串公开的.
例如:
protected TimeSpan myTimeout;
public string MyTimeout
{
get { return myTimeout.ToString(); }
set { myTimeout = TimeSpan.Parse(value); }
}
Run Code Online (Sandbox Code Playgroud)
如果属性值主要用于包含类或继承类并且从xml配置加载,则可以.
如果您希望公共属性成为其他类的可用TimeSpan值,则其他建议的解决方案会更好.
Mik*_*ail 24
结合Color序列化和这个原始解决方案(这本身很棒)的答案我得到了这个解决方案:
[XmlElement(Type = typeof(XmlTimeSpan))]
public TimeSpan TimeSinceLastEvent { get; set; }
Run Code Online (Sandbox Code Playgroud)
其中XmlTimeSpan
类是这样的:
public class XmlTimeSpan
{
private const long TICKS_PER_MS = TimeSpan.TicksPerMillisecond;
private TimeSpan m_value = TimeSpan.Zero;
public XmlTimeSpan() { }
public XmlTimeSpan(TimeSpan source) { m_value = source; }
public static implicit operator TimeSpan?(XmlTimeSpan o)
{
return o == null ? default(TimeSpan?) : o.m_value;
}
public static implicit operator XmlTimeSpan(TimeSpan? o)
{
return o == null ? null : new XmlTimeSpan(o.Value);
}
public static implicit operator TimeSpan(XmlTimeSpan o)
{
return o == null ? default(TimeSpan) : o.m_value;
}
public static implicit operator XmlTimeSpan(TimeSpan o)
{
return o == default(TimeSpan) ? null : new XmlTimeSpan(o);
}
[XmlText]
public long Default
{
get { return m_value.Ticks / TICKS_PER_MS; }
set { m_value = new TimeSpan(value * TICKS_PER_MS); }
}
}
Run Code Online (Sandbox Code Playgroud)
您可以在TimeSpan结构周围创建一个光包装器:
namespace My.XmlSerialization
{
public struct TimeSpan : IXmlSerializable
{
private System.TimeSpan _value;
public static implicit operator TimeSpan(System.TimeSpan value)
{
return new TimeSpan { _value = value };
}
public static implicit operator System.TimeSpan(TimeSpan value)
{
return value._value;
}
public XmlSchema GetSchema()
{
return null;
}
public void ReadXml(XmlReader reader)
{
_value = System.TimeSpan.Parse(reader.ReadContentAsString());
}
public void WriteXml(XmlWriter writer)
{
writer.WriteValue(_value.ToString());
}
}
}
Run Code Online (Sandbox Code Playgroud)
样本序列化结果:
<Entry>
<StartTime>2010-12-06T08:45:12.5</StartTime>
<Duration>2.08:29:35.2500000</Duration>
</Entry>
Run Code Online (Sandbox Code Playgroud)
更可读的选项是序列化为字符串并使用该TimeSpan.Parse
方法对其进行反序列化.您可以在示例中执行相同操作,但TimeSpan.ToString()
在getter和TimeSpan.Parse(value)
setter中使用.
归档时间: |
|
查看次数: |
54378 次 |
最近记录: |