【发布时间】:2011-07-27 17:23:32
【问题描述】:
我使用的是 ProtoBuf-net 版本 2,目前我收到错误“无法确定成员:A”
当我们使用 ClassOfType
顺便说一句:这个请求是根据Deserialize unknown type with protobuf-net 建模的
这是一个工作示例(不工作的内容已删除)。
using System;
using System.IO;
using NUnit.Framework;
using ProtoBuf;
using ProtoBuf.Meta;
namespace ProtoBufTestA2
{
[TestFixture]
public class Tester
{
[Test]
public void TestMsgBaseCreateModel()
{
var BM_SD = new Container<SomeDerived>();
using (var o = BM_SD) {
o.prop1 = 42;
o.payload = new SomeDerived();
using (var d = o.payload) {
d.SomeBaseProp = -42;
d.SomeDerivedProp = 62;
}
}
var BM_SB = new Container<SomeBase>();
using (var o = BM_SB) {
o.prop1 = 42;
o.payload = new SomeBase();
using (var d = o.payload) {
d.SomeBaseProp = 84;
}
}
var model = TypeModel.Create();
model.Add(typeof(Container<SomeDerived>), true); // BM_SD
model.Add(typeof(Container<SomeBase>), true); // BM_SB
model.Add(typeof(SomeBase), true); // SB
model.Add(typeof(SomeDerived), true); // SD
model[typeof(SomeBase)].AddSubType(50, typeof(SomeDerived)); // SD
var ms = new MemoryStream();
model.SerializeWithLengthPrefix(ms, BM_SD, BM_SD.GetType(), ProtoBuf.PrefixStyle.Base128, 0);
model.SerializeWithLengthPrefix(ms, BM_SB, BM_SB.GetType(), ProtoBuf.PrefixStyle.Base128, 0);
ms.Position = 0;
var o1 = (Container<SomeDerived>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeDerived>), PrefixStyle.Base128, 0);
var o2 = (Container<SomeBase>)model.DeserializeWithLengthPrefix(
ms
, null
, typeof(Container<SomeBase>), PrefixStyle.Base128, 0);
}
}
[ProtoContract]
public class Container<T> : IDisposable
{
[ProtoMember(1)]
public int prop1 { get; set; }
[ProtoMember(2)]
public T payload { get; set; }
public void Dispose() { }
}
[ProtoContract]
public class AnotherDerived : SomeDerived, IDisposable
{
[ProtoMember(1)]
public int AnotherDerivedProp { get; set; }
public override void Dispose() { }
}
[ProtoContract]
public class SomeDerived : SomeBase, IDisposable
{
[ProtoMember(1)]
public int SomeDerivedProp { get; set; }
public override void Dispose() { }
}
[ProtoContract]
public class SomeBase : IDisposable
{
[ProtoMember(1)]
public int SomeBaseProp { get; set; }
public virtual void Dispose() { }
}
[ProtoContract]
public class NotInvolved : IDisposable
{
[ProtoMember(1)]
public int NotInvolvedProp { get; set; }
public void Dispose() { }
}
[ProtoContract]
public class AlsoNotInvolved : IDisposable
{
[ProtoMember(1)]
public int AlsoNotInvolvedProp { get; set; }
public void Dispose() { }
}
}
请求
这是次要的,但如果
(Container<SomeDerived>)model.DeserializeWithLengthPrefix(...)
也可以这样实现
model.DeserializeWithLengthPrefix<Container<SomeDerived>>(...):
顺便说一句:我开始深入研究 protobuf-net 实现,并且开始注意到一些像这样的有趣方法。我猜想稍后再讨论:
public MetaType Add(int fieldNumber, string memberName, Type itemType, Type defaultType);
讨论:
当我在上面的链接中看到可以反序列化为抽象基类型的方式时,我想,是的,这更接近于我的想法。我们是否可以先反序列化为开放的通用 Container,然后如果需要在不同的程序集中进行更具体的转换。也许我在这里有点混淆了。
你可以从元组
我有一个非通用序列工作,所以它不是一个展示停止器。我的第一个实现可能会更有效。不过,我认为使用现有的 protobuf-net 功能可以做得更好。
我喜欢以更简洁的通用方式处理这些想法。虽然我可以手动到达同一个目的地,但泛型使其他事情成为可能。
re: 澄清
调用者可以提前定义一切。 (顺便说一句:你现在让我想到了仅运行时的场景,但不,我不需要那个)。
【问题讨论】:
-
Re "无法确定成员:A" - 这仅仅是因为没有名为
A的成员,顺便说一句。同样B,C,D或E。 -
@Marc Gravell 我会看看的。我认为 .Add(1, "A") 也创建了标签。它不能走那么远。说得通。哎呀。
-
@Marc Gravell:我最终一切正常 + 更改了上面的示例代码以反映这一点。再次感谢。让我们把开放的泛型留到其他时间看看。
标签: c# .net protobuf-net