我正在尝试用protobuf-net序列化一些对象,但不幸的是他们自由使用DateTimeOffset了protobuf-net尚未支持的对象.这导致了很多:
没有为类型定义的序列化程序:System.DateTimeOffset
我可以为未知类型定义自己的序列化例程吗?(之前曾问过同样的问题,但他的问题已得到解决.)
如果重要的话,我在.NET 4下使用最新的protobuf-net beta,v2.0.0.431.我也在使用运行时定义,因此我无法以声明方式指定如何处理某些属性.
Mar*_*ell 28
有两种方法可以解决未知"常见"类型的问题; 第一是使用垫片属性,例如,它表示类似的值的东西(一个属性string或long例如):
[ProtoMember(8)]
public string Foo {
get { ... read from the other member ... }
set { ... assign the other member ... }
}
Run Code Online (Sandbox Code Playgroud)
另一种方法是代理,这是第二个自动替代的protobuf合约.使用代理人的要求是:
DateTimeOffset和DateTimeOffsetSurrogate)SetSurrogate(surrogateType)来教育protobuf-netRuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));垫片属性更简单,但需要重复每个成员.代理自动应用于模型中所有类型的实例.然后代理遵循标准的protobuf-net规则,因此您将指出要序列化的成员等.
编辑:添加代码示例
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);
}
}
Run Code Online (Sandbox Code Playgroud)
然后像这样注册
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
Run Code Online (Sandbox Code Playgroud)
Max*_*lev 18
完全尊重Marc Gravell的答案,如果您关心序列化数据的大小,您应该使用以下代理类.输出大小为21个字节而不是35个字节.
using System;
using ProtoBuf;
[ProtoContract]
public class DateTimeOffsetSurrogate
{
[ProtoMember(1)]
public long DateTimeTicks { get; set; }
[ProtoMember(2)]
public short OffsetMinutes { get; set; }
public static implicit operator DateTimeOffsetSurrogate(DateTimeOffset value)
{
return new DateTimeOffsetSurrogate
{
DateTimeTicks = value.Ticks,
OffsetMinutes = (short)value.Offset.TotalMinutes
};
}
public static implicit operator DateTimeOffset(DateTimeOffsetSurrogate value)
{
return new DateTimeOffset(value.DateTimeTicks, TimeSpan.FromMinutes(value.OffsetMinutes));
}
}
Run Code Online (Sandbox Code Playgroud)
然后以完全相同的方式注册它:
RuntimeTypeModel.Default.Add(typeof(DateTimeOffset), false).SetSurrogate(typeof(DateTimeOffsetSurrogate));
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
5595 次 |
| 最近记录: |