问题
I have a DateRange
object that represents the notion of Infinity via Static reference as shown below. As you see, the end points that define Infinity are also static references in a different class, DatePoint.Past
and DatePoint.Future
.
Now I need to serialize this (as part of a deep Clone method that uses serialization) and know when it's deserialized that an instance with DateTime.Min
and DateTime.Max
as endpoints then the instance should be DateRange.Infinity
. So I think I need to make it ISerializable
.
My first attempt at implementing ISerializable
is quite poor; and but I'm showing it in the hopes it suggests a quicker fix to someone. I have used some similar code for NHibernate to store DateRange
in the db and reconstitue Infinity, but I'm not getting how to apply that for serialization yet.
DatePoint
is marked [Serializable]
but does not implement ISerializable
.
edited question
I am not looking to serialize/deserialize Infinity. What I am looking for is a hook into where I can take the deserialized DataRange
and decide if it is equivalent to Infinity
.
**
Cheers, 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;
}
First ISerializable attempt
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)
{
}
回答1:
You can implement IObjectReference
and replace the object after deserialization:
object IObjectReference.GetRealObject(StreamingContext context)
{
if (Start.Equals(DatePoint.Past) && End.Equals(DatePoint.Future))
{
return Infinity;
}
}
See the documentation.
回答2:
You cannot create an instance of a static member, and therefore they cannot be serialized or deserialized.
You may instead create a proper public property with a protected set
which doesn't do anything and a get
which returns the result you want. The property can then be serialized, but not deserialized because that would be an exercise in futility...
回答3:
I do NOT like answering my own question, but here is a solution that seems to work. Probably I just didn't ask the question right in the first place, and I didn't know how to do the below when I asked it.
Someone sees a better way to do it, please say so!
Cheers,
Berryl
Make DateRange implement 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));
}
来源:https://stackoverflow.com/questions/12692860/hooking-into-the-deserialization-process