挂钩反序列化过程

时间:2012-10-02 14:59:37

标签: c# serialization binaryformatter

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

现在我需要对此进行序列化(作为使用序列化的深度克隆方法的一部分)并知道在反序列化时将DateTime.MinDateTime.Max作为端点的实例然后实例应该是DateRange.Infinity 。所以我想我需要做到ISerializable

我实施ISerializable的第一次尝试非常糟糕;但是我希望它表明它可以更快地解决某个问题。我已经使用一些类似的NHibernate代码将DateRange存储在db中并重新构建Infinity,但我还没有得到如何应用它来进行序列化。

DatePoint已标记为[Serializable],但未实施ISerializable

已编辑的问题

我不打算序列化/反序列化Infinity。我 寻找的内容是我可以接受反序列化的DataRange并确定它是否等同于Infinity

**

干杯, Berryl

DATERANGE

[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; }

}

DatePoint

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

3 个答案:

答案 0 :(得分:2)

您无法创建静态成员的实例,因此无法对其进行序列化或反序列化。

您可以创建一个合适的公共属性,其中protected set不执行任何操作,而get会返回您想要的结果。然后可以对属性进行序列化,但不进行反序列化,因为这样做是徒劳的......

答案 1 :(得分:1)

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

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

请参阅documentation

答案 2 :(得分:0)

NOT 就像回答我自己的问题一样,但这是一个似乎有效的解决方案。可能我刚才没有问过这个问题,当我提出问题时我不知道怎么做。

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

干杯,
Berryl

使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));
    }