There are two ways of approaching the issue of unknown "common" types; the first is to use a shim property, for example a property that represents the value as something similar (a string
or long
for example):
[ProtoMember(8)]
public string Foo {
get { ... read from the other member ... }
set { ... assign the other member ... }
}
The other approach is a surrogate, which is a second protobuf contract that is automatically substituted. The requirements to use a surrogate are:
- there must be a defined conversion operator (implicit or explict) between the two types (for example,
DateTimeOffset
and DateTimeOffsetSurrogate
)
- you then use
SetSurrogate(surrogateType)
to educate protobuf-net, for example RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
the shim property is simpler, but requires repeat per-member. The surrogate is applied automatically to all instances of the type within the model. The surrogate then follows standard protobuf-net rules, so you would indicate which members to serialize, etc.
EDIT: Adding code example
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);
}
}
Then register it like this
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));