Hay dos formas de abordar el problema de los tipos "comunes" desconocidos; el primero es el uso de una propiedad de cuña, por ejemplo una propiedad que representa el valor como algo similar (un string
o long
por ejemplo):
[ProtoMember(8)]
public string Foo {
get { ... read from the other member ... }
set { ... assign the other member ... }
}
El otro enfoque es una sustituto, que es un segundo protobuf contrato que se sustituye automáticamente. Los requisitos para utilizar un sustituto son:
- Tiene que ser un operador definido conversión (implícita o explict) entre los dos tipos (por ejemplo,
DateTimeOffset
y DateTimeOffsetSurrogate
)
- a continuación, utiliza
SetSurrogate(surrogateType)
para educar protobuf-net , por ejemplo RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
la propiedad shim es más simple, pero requiere repetición por miembro. El suplente se aplica automáticamente a todas las instancias del tipo dentro del modelo. El sustituto continuación, sigue las reglas protobuf-net estándar, lo que indicaría que los miembros serializar, etc.
EDIT: Adición de ejemplo de código
using System;
using ProtoBuf;
[ProtoContract]
public class DateTimeOffsetSurrogate
{
[ProtoMember(1)]
public string DateTimeString { get; set; }
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset value)
{
return new DateTimeOffsetSurrogate {DateTimeString = value.ToString("u")};
}
public static implicit operator DateTimeOffset(DateTimeOffsetSurrogate value)
{
return DateTimeOffset.Parse(value.DateTimeString);
}
}
A continuación, registrarlo como esto
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
Todo bien, excepto que debería ser 'value.ToString ("O")', 'no "u" '. De lo contrario, perderá la información de compensación (zona horaria). –
¿Cómo otras bibliotecas de protobuf deserializarían el resultado de esto? Si tuvieras un padre de la clase con una propiedad de tipo DateTimeOffset, ¿la otra biblioteca también necesitará un tipo sustituto con una propiedad de cadena? o puede la clase Parent en el otro sistema simplemente usar un tipo de cadena para la propiedad (asumiendo en otro idioma que no tiene un tipo DateTimeOffset)? –
ejemplo: https://gist.github.com/rushfrisby/4377bb0efc1478c14221 –