-
12-12-2019 - |
题
我有一个 DateRange
通过静态引用表示无限概念的对象,如下所示。如您所见,定义 Infinity 的端点也是不同类中的静态引用, DatePoint.Past
和 DatePoint.Future
.
现在我需要序列化它(作为使用序列化的深度克隆方法的一部分)并知道 当反序列化一个实例时 DateTime.Min
和 DateTime.Max
作为端点,那么实例应该是 DateRange.Infinity
. 。所以我想我需要做到 ISerializable
.
我第一次尝试实施 ISerializable
很穷;但我展示它是希望它能为某人提供更快的解决方案。我使用了 NHibernate 的一些类似代码来存储 DateRange
在数据库中并重新构建 Infinity,但我还不知道如何将其应用于序列化。
DatePoint
被标记 [Serializable]
但没有实施 ISerializable
.
编辑过的问题
我不想序列化/反序列化 Infinity。我什么 是 寻找的是一个钩子,我可以在其中进行反序列化 DataRange
并判断它是否等于 Infinity
.
**
欢呼,贝里尔
日期范围
[Serializable]
[TypeConverter(typeof(DateRangeTypeConverter))]
public class DateRange : ValueObject, IRange<DatePoint, DateRange, TimeSpan>, ISerializable
{
/// <summary>
/// Returns a range spanning <see cref="DatePoint.Past"/> and <see cref="DatePoint.Future"/>.
/// </summary>
public static readonly DateRange Infinity = new DateRange(DatePoint.Past, DatePoint.Future);
/// <summary> The start of the <see cref="DateRange"/> range. </summary>
public DatePoint Start { get; protected set; }
/// <summary> The end of the <see cref="DateRange"/> range. </summary>
public DatePoint End { get; protected set; }
}
日期点
public class DatePoint : ValueObject, IComparable<DatePoint>, IComparable<DateTime>, IComparable, IEquatable<DatePoint>, IEquatable<DateTime>, IFormattable
{
/// <summary>The undefined infinite past, smaller than any other date except itself.</summary>
public readonly static DatePoint Past = DateTime.MinValue;
/// <summary>The undefined infinite future, larger than any other date except itself.</summary>
public readonly static DatePoint Future = DateTime.MaxValue;
}
第一次 ISerialized 尝试
protected DateRange(SerializationInfo info, StreamingContext ctx) {
if (info == null)
throw new System.ArgumentNullException("info");
var start = (DatePoint)info.GetValue("Start", typeof(DatePoint));
var end = (DatePoint)info.GetValue("End", typeof(DatePoint));
// its Infinity if so
if((start.Equals(DatePoint.Past) && end.Equals(DatePoint.Future)))
return;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
}
解决方案
你可以实施 IObjectReference
并在反序列化后替换对象:
object IObjectReference.GetRealObject(StreamingContext context)
{
if (Start.Equals(DatePoint.Past) && End.Equals(DatePoint.Future))
{
return Infinity;
}
}
请参阅 文档.
其他提示
您无法创建静态成员的实例,因此无法对它们进行序列化或反序列化。
相反,您可以创建一个适当的公共财产 protected set
它什么也不做,并且 get
它返回你想要的结果。然后该属性可以被序列化,但不能反序列化,因为这将是徒劳的......
我愿意 不是 就像回答我自己的问题一样,但这里有一个似乎有效的解决方案。可能我一开始就没有问清楚这个问题,当我问的时候我不知道该怎么做。
有人看到更好的方法,请说出来!
干杯,
贝里尔
使 DateRange 实现 ISerialized
protected DateRange(SerializationInfo info, StreamingContext context) {
if (info == null)
throw new ArgumentNullException("info");
var foundPast = (bool) info.GetValue("thePast", typeof (bool));
if (foundPast)
Start = DatePoint.Past;
var foundFuture = (bool) info.GetValue("theFuture", typeof (bool));
if (foundFuture)
End = DatePoint.Future;
}
public void GetObjectData(SerializationInfo info, StreamingContext context)
{
info.AddValue("thePast", Start.Equals(DatePoint.Past), typeof(bool));
info.AddValue("theFuture", End.Equals(DatePoint.Future), typeof(bool));
}