没有为类型定义的序列化程序:System.Windows.Media.Media3D.Point3D

我正在尝试使用protobuf net序列化一些数据。 在序列化期间,我收到一个错误,没有为Point3D类型定义序列化。 我发现了一个像这样的问题,但仍然无法实现和解决它。 链接如下: – 没有为类型定义的序列化程序:System.Drawing.Color

[ProtoContract] public class ReturnPanelData { [ProtoMember(1)] public Point3D PlacedPoint3D { get; set; } [ProtoMember(2)] public double PlacementAngle { get; set; } [ProtoMember(3)] public string PanelName { get; set; } } [ProtoContract] public class ReturnDataType { [ProtoMember(1)] public List ReturnList { get; set; } [ProtoMember(2)] public double RemainderArea { get; set; } [ProtoMember(3)] public int Height { get; set; } [ProtoMember(4)] public int Width { get; set; } [ProtoMember(5)] public Point3D BasePoint3D { get; set; } } class Program { private static HashSet _processedList = new HashSet(); static void Main(string[] args) { using (var file = File.Create(@"D:\SavedPCInfo2.bin")) { Serializer.Serialize(file, _processedList); } Console.WriteLine("Done"); } } 

我是JSON序列化/反序列化的初学者。 如何解决这个问题?

如果无法使用Protobuf Net序列化Point3D,那么序列化/反序列化一个非常大的列表(有大约300000个项目)的其他选项有哪些?

首先, protobuf-net不是JSON序列化程序。 它序列化为“协议缓冲区” – 这是Google用于大部分数据通信的二进制序列化格式。

话虽如此,有几种使用protobuf-net序列化类型的解决方案,无法使用ProtoContract属性进行修饰:

  1. 如果包含其他类型,请使用代理或“shim”属性,如此处所示,或者
  2. 使用此处所示的代理,或者
  3. 在运行时,请向RuntimeTypeModel讲述该类型的所有可序列化字段和属性,如“ 无属性序列化 ”一节中所述。

对于选项2,由于Point3D完全由其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所有类。