1

我有一个DateRange通过静态引用表示无限概念的对象,如下所示。如您所见,定义 Infinity 的端点也是不同类中的静态引用,DatePoint.Past并且DatePoint.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;

}

第一次 ISerializable 尝试

    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)
    {
    }
4

3 回答 3

2

您不能创建静态成员的实例,因此它们不能被序列化或反序列化。

您可以改为创建一个适当的公共属性,其中 aprotected set什么都不做, aget返回您想要的结果。然后可以序列化该属性,但不能反序列化,因为那将是徒劳的……

于 2012-10-02T15:06:31.907 回答
1

您可以IObjectReference在反序列化后实现和替换对象:

object IObjectReference.GetRealObject(StreamingContext context)
{
    if (Start.Equals(DatePoint.Past) && End.Equals(DatePoint.Future))
    {
        return Infinity;
    }
}

请参阅文档

于 2012-10-03T06:31:22.310 回答
0

喜欢回答我自己的问题,但这里有一个似乎可行的解决方案。可能我一开始就没有问正确的问题,当我问这个问题时,我不知道该怎么做。

有人看到了更好的方法,请说出来!

干杯,
贝里尔

使 DateRange 实现 ISerializable

    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));
    }
于 2012-10-02T17:12:31.353 回答