我有一个 DateRange 通过静态引用表示无限概念的对象,如下所示。如您所见,定义 Infinity 的端点也是不同类中的静态引用, DatePoint.PastDatePoint.Future.

现在我需要序列化它(作为使用序列化的深度克隆方法的一部分)并知道 当反序列化一个实例时 DateTime.MinDateTime.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));
    }
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top