【问题标题】:ProtoBuf-Net , Open generic types serialization/ deserializationProtoBuf-Net,开放泛型类型序列化/反序列化
【发布时间】:2012-02-27 09:31:14
【问题描述】:

我有以下类型:

Class Command<TData> : Base Where TData : I

在运行时,这个类被构建(带有特定的 TDATA)和序列化。 我有 2 个问题(我正在使用 V2): 1)当我将此类型添加到运行时模式时:

var meta = this._modal.Add(type, false)
                             .Add(this.GetDMProperties(type).Select(p => p.Name)
                             .ToArray());

我得到以下异常:

未处理的异常:System.NullReferenceException:对象引用未设置为 一个对象的实例。 在 C:\Dev\protobuf-net\protobuf-net\Meta\TypeModel.cs:line 952 中的 ProtoBuf.Meta.TypeModel.ResolveProxies(Type type) 在 C:\Dev\protobuf-net\protobuf-net\Meta\RuntimeTypeModel.cs:line 118 中的 ProtoBuf.Meta.RuntimeTypeModel.FindWithoutAdd(Type type) 在 ProtoBuf.Meta.ValueMember..ctor(RuntimeTypeModel 模型,类型 parentType,Int32 fieldNumber,MemberInfo 成员,类型 memberType,类型 itemType,类型默认值 C:\Dev\protobuf-net\protobuf-net\Meta\ValueMember.cs:line 75 中的 tType、DataFormat dataFormat、Object defaultValue) 在 C:\Dev\protobuf-net\protobu 中的 ProtoBuf.Meta.MetaType.AddField(Int32 fieldNumber, String memberName, Type itemType, Type defaultType, Object defaultValue) f-net\Meta\MetaType.cs:第 1165 行 在 C:\Dev\protobuf-net\protobuf-net\Meta\MetaType.cs:line 1046 中的 ProtoBuf.Meta.MetaType.Add(String[] memberNames) 处

2) 如果我尝试在启动时跳过它并尝试像下面这样按需执行:

if (this._modal.CanSerializeContractType(objectType) == false)
            {
                this._modal.Add(objectType, false);
                this._modal.CompileInPlace();
            }

CanSerializeContractType 返回 true,但实际上只对基础数据进行序列化。

我的问题是如果可能的话,将这种类型添加到模态而不在设计时添加所有排列的做法是什么?

【问题讨论】:

  • 你好;我试图重现您的 2 个问题(例外,以及 CanSerialize... 的问题) - 也无法重现 - here's my test - 你能添加任何上下文来帮助我重现吗?关于第二个,我想知道 CanSerialize... 最初是否报告 false,然后您 Add 它,但您没有添加任何要序列化的成员 - 这是问题吗?
  • 我添加了代码
  • sn-p 不允许我重现该场景——尤其是整个“类型”程序集。我可以伪造一些东西,但我不能保证我正在研究同样的问题。有什么方法可以减少这个问题,也许只需要一个具体的类,我可以用它来重现这个问题?
  • link 代码,最后是类型程序集。如果还有什么我可以帮你复制的,请告诉我
  • k;我现在有一个重现,谢谢 - 它与开放的泛型类型有关(type == T,没有具体的T)。我会看看我能做什么(解决这个问题很容易 - 我的意思更多:想办法解决这个场景)

标签: generics protobuf-net


【解决方案1】:

我将不得不调查第一个;听起来像一个奇怪的边缘案例错误。但是,您的第二点与我不久前的一次对话有关 - 结论是我将添加一个在第一次看到类型时触发的事件。然后,您将有机会在配置类型的事件期间。理论上:简单;我只需要实现它。我会在我的清单上“碰撞”这个转发......

附注:除非您只在单个 AppDomain 中工作,而不是写入磁盘或通过网络或进程之间发送,否则您必须确保您可以可靠地添加属性/sun-types相同的键。或者更具体地说:您的 GetDMaproperties 方法(未显示)需要某种固定顺序,或者您需要 LINQ 中的 OrderBy。还;这很脆弱 - 如果有人添加/删除/重命名属性,键将会改变。

【讨论】:

  • 感谢您的及时回复。我只是想知道如果不添加新事件,上述是否不可行? , 其次是属性标签必须是唯一的还是它们表现为 DataMember 顺序?
  • @eyan 好吧,你可以用属性来装饰;但除此之外......目前没有。 Re "second" - 每个类型必须是唯一的
  • 谢谢,有没有办法实现版本容错?您可以直接访问博客或其他方式来解释序列化程序的一些“高级”用法吗? (作为参考......)。再次感谢。
  • @eyan 因为 protobuf 不存储字段名称,为了版本容错,我强烈建议:将键/名称映射存储在某处
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2012-04-26
  • 2010-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多