31

これが重複している場合は申し訳ありません。私はいくつかの場所を検索して、私が理解できるかもしれない答えを探しました。

派生クラスをシリアル化する場合、ProtoBuf.net基本クラスのプロパティは含まれません

protobuf-netを使用して継承されたクラスをシリアル化する

申し訳ありませんが、答えがよくわかりませんでした。より高速でコンパクトなバイナリシリアライザーを探していますが、ProtoBufがその答えのようです。すべてが単一の基本クラスから派生するクラスのセットをシリアル化する必要があります。それらはたくさんあるので、クラスコードの編集をコミットする前に、簡単なテストを実行しました。また、NETバイナリシリアライザーで生成された古い永続ファイルの逆シリアル化に影響を与える可能性のある方法でクラスを変更したくありません。

これは基本クラスです:

[ProtoContract]
    public class BaseClass
    {
        [ProtoMember(1)]
        public string Name
        {
            get; set;
        }
        [ProtoMember(2)]
        public int Age
        {
            get; set;
        }
    }

これは派生クラスです:

[ProtoContract]
    public class SubClass1 : BaseClass
    {
        [ProtoMember(3)]
        public string Town
        {
            get; set;
        }

        [ProtoMember(4)]
        public Sex Sex
        {
            get; set;
        }
    }

これは、シリアル化および逆シリアル化するためのコードです(スタートガイドから直接取得)

var person = new SubClass1 { Age = 25, Name = "Fred", Town = "Denbigh", Sex = Sex.Female };

            using (var file = File.Create(filename))
            {
                Serializer.Serialize(file, person);
            }

および逆シリアル化:

SubClass1 newPerson;
            using (var file = File.OpenRead(filename))
            {
                newPerson = Serializer.Deserialize<SubClass1>(file);
            }

            MessageBox.Show(newPerson.Name + 
                " : " + newPerson.Town + 
                " : " + newPerson.Age.ToString() + 
                " : " + newPerson.Sex);

結果は「:デンビー:0:女性」です。

どういうわけか、基本クラスのプロパティの値がシリアル化されていませんか?私はもともと、派生クラスのProtoMemberインデックスを1、2としてテストしましたが、うまくいかないと思ったので、3、4に行きました。違いはないようです。私のパラノイアでは、標準のNETバイナリシリアライザーを使用して同じテストを実行し、期待される結果が得られました:「フレッド:デンビー:25:女性」

何が足りないの?

4

2 に答える 2

34

ProtoInclude基本クラスで属性を使用する必要があります。

[ProtoContract]
[ProtoInclude(500, typeof(SubClass1 ))]
public class BaseClass
{

id arg(上記の例では500)は、そのクラスに固有である必要があります。詳細については、この記事を参照してください

于 2012-10-20T13:50:23.727 に答える
1

私はそれがかなり古いことを知っていますが、誰かを助けるかもしれません。場合によっては、サブタイプの基本プロパティを再定義することでこれを修正できます。

[ProtoContract]
public class SubClass1 : BaseClass
{
    [ProtoMember(1)]
    public string BaseName
    {
        get{return base.Name;}
        set{base.Name = value;}
    }

    ...

    [ProtoMember(3)]
    public string Town
    {
        get; set;
    }

    [ProtoMember(4)]
    public Sex Sex
    {
        get; set;
    }
}
于 2015-09-23T09:59:50.757 に答える