conectando-se ao processo de desserialização
-
12-12-2019 - |
Pergunta
eu tenho um DateRange
objeto que representa a noção de Infinito via referência estática conforme mostrado abaixo.Como você pode ver, os pontos finais que definem o Infinity também são referências estáticas em uma classe diferente, DatePoint.Past
e DatePoint.Future
.
Agora preciso serializar isso (como parte de um método Clone profundo que usa serialização) e saber quando é desserializado que uma instância com DateTime.Min
e DateTime.Max
como endpoints, então a instância deve ser DateRange.Infinity
.Então eu acho que preciso fazer isso ISerializable
.
Minha primeira tentativa de implementação ISerializable
é bastante pobre;e mas estou mostrando isso na esperança de sugerir uma solução mais rápida para alguém.Eu usei um código semelhante para o NHibernate armazenar DateRange
no banco de dados e reconstituir o Infinity, mas ainda não estou conseguindo aplicar isso para serialização.
DatePoint
é marcado [Serializable]
mas não implementa ISerializable
.
pergunta editada
Não estou procurando serializar/desserializar o Infinity.O que eu sou procurando é um gancho para onde posso levar o desserializado DataRange
e decida se é equivalente a Infinity
.
**
Saúde, Berryl
Intervalo de datas
[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; }
}
Ponto de data
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;
}
Primeira tentativa 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)
{
}
Solução
Você pode implementar IObjectReference
e substitua o objeto após a desserialização:
object IObjectReference.GetRealObject(StreamingContext context)
{
if (Start.Equals(DatePoint.Past) && End.Equals(DatePoint.Future))
{
return Infinity;
}
}
Veja o documentação.
Outras dicas
Você não pode criar uma instância de um membro estático e, portanto, eles não podem ser serializados ou desserializados.
Em vez disso, você pode criar uma propriedade pública adequada com um protected set
que não faz nada e um get
que retorna o resultado que você deseja.A propriedade pode então ser serializada, mas não desserializada porque isso seria um exercício de futilidade...
Eu faço NÃO gosto de responder à minha própria pergunta, mas aqui está uma solução que parece funcionar.Provavelmente eu simplesmente não fiz a pergunta certa em primeiro lugar e não sabia como fazer o que está abaixo quando a fiz.
Alguém vê uma maneira melhor de fazer isso, por favor, diga!
Saúde,
Berryl
Faça DateRange implementar 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));
}