Ответ 1
Существует два способа приближения к проблеме неизвестных "общих" типов; во-первых, использовать свойство shim, например свойство, которое представляет значение как нечто похожее (например, string
или long
):
[ProtoMember(8)]
public string Foo {
get { ... read from the other member ... }
set { ... assign the other member ... }
}
Другой подход - это суррогат, который является вторым контрактом protobuf, который автоматически заменяется. Требования к использованию суррогата заключаются в следующем:
- должен существовать определенный оператор преобразования (неявный или эксплицированный) между двумя типами (например,
DateTimeOffset
иDateTimeOffsetSurrogate
) - затем используйте
SetSurrogate(surrogateType)
для обучения protobuf-net, напримерRuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
свойство shim проще, но требует повторения для элемента. Суррогат применяется автоматически ко всем экземплярам типа в модели. Затем суррогат следует стандартным правилам protobuf-net, поэтому вы указываете, какие члены сериализуются и т.д.
EDIT: добавление примера кода
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);
}
}
Затем зарегистрируйте его следующим образом
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));