1

リフレクションによってロードされた 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 を使用していることに注意してください。ありがとう、

4

2 に答える 2

0

わかった; 現在のトランク コードを実行しました。最初はエラー処理ImplicitFieldsが発生しましたが、ローカルで修正しました。それを実行すると、次のようになります。

37
37

これは、最後の (625-431)=194 がコミットされた場合、問題はすでに修正されていることを示唆しています。どっちか聞かないで!r625 を試してみることをお勧めします。まだデプロイしていませんが、protobuf-net プロジェクトがビルドされるはずです。または、メールで送ってほしい場合はお知らせください。

また、非汎用 API を使用する方が簡単な場合がありますMakeGenericMethod。、ProtoBuf.Serializer.NonGenericまたはProtoBuf.RuntimeTypeModel.Default(基本的に、 v2 コアがすべてのジェネリック コードを削除したため、ジェネリックAPI は 非ジェネリックSerializerAPIに転送されるだけになりました。ジェネリック API を使用する利点は、利便性以外にまったくありません。リフレクションを使用する場合はありません)。

于 2013-01-28T22:25:34.043 に答える
0

間違った順序

[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; }
}
于 2013-01-26T20:01:29.847 に答える