首先,protobuf网络 https://github.com/mgravell/protobuf-net不是一个JSON http://json.org/序列化器。它序列化从和到“协议缓冲区” https://www.nuget.org/packages/protobuf-net/- Google 用于大部分数据通信的二进制序列化格式。
话虽这么说,有几种解决方案可以使用 protobuf-net 序列化类型,但不能用ProtoContract
属性:
- 当被其他类型包含时,请使用代理或“shim”属性,如图所示here https://stackoverflow.com/questions/7046506/can-i-serialize-arbitrary-types-with-protobuf-net, OR
- 使用如图所示的代理here https://stackoverflow.com/questions/7046506/can-i-serialize-arbitrary-types-with-protobuf-net, OR
- 在运行时教导RuntimeTypeModel https://github.com/mgravell/protobuf-net/blob/master/protobuf-net/Meta/RuntimeTypeModel.cs关于所述类型的所有可序列化字段和属性here http://www.codeproject.com/Articles/642677/Protobuf-net-the-unofficial-manual在该部分不带属性的序列化.
对于选项 2,由于Point3D https://msdn.microsoft.com/en-us/library/system.windows.media.media3d.point3d.aspx完全由其 X、Y 和 Z 坐标定义,引入序列化代理非常容易:
[ProtoContract]
struct Point3DSurrogate
{
public Point3DSurrogate(double x, double y, double z) : this()
{
this.X = x;
this.Y = y;
this.Z = z;
}
[ProtoMember(1)]
public double X { get; set; }
[ProtoMember(2)]
public double Y { get; set; }
[ProtoMember(3)]
public double Z { get; set; }
public static implicit operator Point3D(Point3DSurrogate surrogate)
{
return new Point3D(surrogate.X, surrogate.Y, surrogate.Z);
}
public static implicit operator Point3DSurrogate(Point3D point)
{
return new Point3DSurrogate(point.X, point.Y, point.Z);
}
}
然后在启动时向 protobuf-net 注册一次,如下所示:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), false).SetSurrogate(typeof(Point3DSurrogate));
或者,对于选项 3,在启动时您可以定义一个合约Point3D
像这样:
ProtoBuf.Meta.RuntimeTypeModel.Default.Add(typeof(Point3D), true);
ProtoBuf.Meta.RuntimeTypeModel.Default[typeof(Point3D)].Add(1, "X").Add(2, "Y").Add(3, "Z");
(在我看来,尽管需要更多代码,但代理更清晰;完全在运行时定义协议似乎太繁琐了。)
我不推荐选项 1,因为您需要向所有使用的类添加代理属性Point3D
.