为 protobuf-net 生成序列化程序集失败

Posted

技术标签:

【中文标题】为 protobuf-net 生成序列化程序集失败【英文标题】:Generating serialization assembly fails for protobuf-net 【发布时间】:2012-08-10 05:33:17 【问题描述】:

我正在尝试使用precompile.exe 工具生成可在Windows Phone 7 程序中使用的序列化程序集。我拥有的数据模型使用继承 - 并且作为 .NET 4.0 程序运行得很好(序列化有效)。但是,在尝试生成序列化程序集时,出现错误:

Adding Program.Serialization.MessagePeer...
A type can only participate in one inheritance hierarchy
at ProtoBuf.Meta.MetaType.SetBaseType(MetaType baseType) in c:\Dev\protobuf-net\protobuf-net\Meta\MetaType.cs:line 138
at ProtoBuf.Meta.MetaType.AddSubType(Int32 fieldNumber, Type derivedType, DataFormat dataFormat) in c:\Dev\protobuf-net\protobuf-net\Meta\MetaType.cs:line 125
at ProtoBuf.Meta.MetaType.ApplyDefaultBehaviour() in c:\Dev\protobuf-net\protobuf-net\Meta\MetaType.cs:line 553
at ProtoBuf.Meta.RuntimeTypeModel.Add(Type type, Boolean applyDefaultBehaviour) in C:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 494
at ProtoBuf.Precompile.PreCompileContext.Execute() in c:\Dev\protobuf-net\precompile\Program.cs:line 340
at ProtoBuf.Precompile.Program.Main(String[] args) in c:\Dev\protobuf-net\precompile\Program.cs:line 33

我已经能够使用更简单的数据模型重现该问题:

[ProtoContract]
[ProtoInclude(2, typeof(Bar))]
public abstract class Foo

    [ProtoMember(1)]
    public int Value  get; set; 


[ProtoContract]
public class Bar : Foo

    [ProtoMember(2)]
    public string Name  get; set; 

我已经尝试使用来自http://code.google.com/p/protobuf-net/ 的 protobuf 的 r284 和 2485 版本。

precompile.exe 的命令行也很简单:

D:\Projects\Program\Precompile>precompile
   "..\SerializerGen\bin\Debug\SerializerGen.dll"
   -o:MySerialization.dll
   -t:MyProgram.Serialization.PeerMessageSerializer

这是 protobuf-net 中的一个已知问题,还是我做错了什么?

【问题讨论】:

有趣;我有一个repro并将调查。作为旁注,该模型不可能工作 - Foo 上有一个重复的字段 1 - 在复制/粘贴过程中是否有问题? (这不会影响您看到的错误,但它让我怀疑“并且作为 .NET 4.0 程序运行得很好”) 糟糕,这是剪切/粘贴错误,我会修复示例。出于好奇,问题是什么?我短暂地尝试过调试它,但后来意识到我对逻辑的理解不够,没有更多地研究它以提出快速(和正确)的修复。 【参考方案1】:

嗯; System.Reflection 和 IKVM.Reflection 报告继承属性的方式略有不同,即预编译器(使用 IKVM.Reflection)看到 inherited ProtoIncludeAttribute,加上 2(而不是 1 )ProtoContractAttributes.

这是在 r571 中修复的

【讨论】:

嗯,修复可能不完整 - 下载并使用 r571 后,预编译步骤成功,但尝试使用生成的 Serializer 类会在 Serialize() 调用中导致 MissingMethodException @LBushkin 等一下,我去看看 @LBushkin 无法重现;我有一个 phone-7 项目,使用以下代码运行良好:var ser = new so11::MySerializer(); SO11895998.Foo foo = new SO11895998.Bar Name = "abc", Value = 4; var clone = (SO11895998.Bar) ser.DeepClone(foo); Debug.Assert(clone.Name == "abc"); Debug.Assert(clone.Value == 4); - 你有没有机会提供更多关于它所说的错误的信息? @LBushkin(so11: 只是因为我在这个项目中有多个MySerializer ;p) Marc,当您运行 precompile 时,您针对 WP7 的目标是哪个 .NET 框架?

以上是关于为 protobuf-net 生成序列化程序集失败的主要内容,如果未能解决你的问题,请参考以下文章

Protobuf-net 序列化错误 =“一旦生成了序列化程序,就无法更改类型”

protobuf-net 中没有为 System.Version 定义序列化程序

使用 protobuf-net 为 Windows 商店应用程序序列化私有成员

对象(通用)的 Protobuf-net 序列化抛出错误没有为类型定义序列化程序:System.Object

protobuf-net 版本容差

Protobuf-net 使用嵌套数据反序列化时出现无效的线型异常(C++ 到 C#)