【问题标题】:Proto Serializing hierarchy type with Reflection使用反射的原型序列化层次结构类型
【发布时间】:2013-01-10 13:00:04
【问题描述】:

当尝试使用已通过反射加载的 proto 序列化程序对层次结构类型进行序列化时,它似乎有一些奇怪的行为,并且似乎并没有真正起作用。

代码如下:

    [ProtoContract]
    [ProtoInclude(10, typeof(Derived))]
    class Base
    {
        [ProtoMember(1)]
        public string BaseFirstProperty { get; set; }
        [ProtoMember(2)]
        public string BaseSecProperty { get; set; }
    }

    [ProtoContract]
    class Derived : Base
    {
        [ProtoMember(1)]
        public string DerivedFirstProperty { get; set; }
    }

    static void Main(string[] args)
    {
        var assembly = Assembly.LoadFile(@"c:\protobuf-net.dll");

        var derived = new Derived()
        {
            BaseFirstProperty = "BaseFirst",
            BaseSecProperty = "BaseSec",
            DerivedFirstProperty = "DerivedFirst"
        };

        var reflectionSerializer = assembly.GetType("ProtoBuf.Serializer");
        var getTypeSerializer = typeof(Serializer);

        var reflectionMethods = reflectionSerializer.GetMethods(BindingFlags.Static | BindingFlags.Public);
        var reflectionGenericMethodInfo = reflectionMethods.First<MethodInfo>(method => method.Name == "SerializeWithLengthPrefix");
        var reflectionSpecificMethodInfo = reflectionGenericMethodInfo.MakeGenericMethod(new Type[] { derived.GetType() });

        var getTypeMethods = getTypeSerializer.GetMethods(BindingFlags.Static | BindingFlags.Public);
        var getTypeGenericMethodInfo = getTypeMethods.First<MethodInfo>(method => method.Name == "SerializeWithLengthPrefix");
        var getTypeSpecificMethodInfo = getTypeGenericMethodInfo.MakeGenericMethod(new Type[] { derived.GetType() });

        var reflectionStream = new MemoryStream();
        var getTypeStream = new MemoryStream();
        reflectionSpecificMethodInfo.Invoke(null, new object[] { reflectionStream, derived, PrefixStyle.Base128 });
        getTypeSpecificMethodInfo.Invoke(null, new object[] { getTypeStream, derived, PrefixStyle.Base128 });

        Console.WriteLine(reflectionStream.ToArray().Length); // Prints out 15
        Console.WriteLine(getTypeStream.ToArray().Length); // Prints out 37
    }

据我所知,它应该是一样的......我做错了什么? 请注意,我使用的是 Proto-buf 2.0.0.431。 谢谢,

【问题讨论】:

  • 看过问题;会看起来,但也有日常工作要做

标签: .net serialization reflection protocol-buffers protobuf-net


【解决方案1】:

顺序错误

[ProtoContract]
[ProtoInclude(10, typeof(Derived))]
class Base
{
    [ProtoMember(1)]
    public string BaseFirstProperty { get; set; }
    [ProtoMember(2)]
    public string BaseSecProperty { get; set; }
}

[ProtoContract]
class Derived : Base
{
    [ProtoMember(3)]
    public string DerivedFirstProperty { get; set; }
}

【讨论】:

    【解决方案2】:

    好的;我已经通过当前的主干代码运行它;我最初在处理 ImplicitFields 时遇到错误,但我已在本地更正了该错误。然后运行它,我得到:

    37
    37
    

    这向我表明,如果最后一次 (625-431)=194 提交,问题已经解决。别问我是哪一个!我建议您尝试 r625 看看效果如何,我还没有部署它,但是应该构建 protobuf-net 项目,或者如果您希望我通过电子邮件将其发送给您,请告诉我。

    另外:您可能会发现使用非通用 API 比使用MakeGenericMethod 更容易;要么是ProtoBuf.Serializer.NonGeneric,要么是ProtoBuf.RuntimeTypeModel.Default(基本上,generic Serializer API 现在只是转发到 non-generic API,因为 v2 核心被淘汰了所有通用代码;使用通用 API 绝对没有任何优势,除了方便 - 使用反射时您没有)。

    【讨论】:

    • 嗨,Matc,我已经用 622 进行了尝试,也得到了 ImplicitFields 错误。 “在本地更正它”是什么意思?请务必将 r625 发送给我。
    • @Moti 是的,
    • 它就像一个魅力.. 所以我只需要等待下一个稳定版本。谢谢!
    • @Moti 在部署公共构建之前,我想整理几件事(与此完全无关) - 希望在周末进行
    • 太棒了!比我想象的要早!谢谢!
    猜你喜欢
    • 2019-04-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多