3

次の基本クラスがあるとします。

[DataContract]
[Serializable]
public abstract class DimensionEntity
{
    [DataMember(Order = 1)]
    private readonly Date effectiveDatespan;
    ...
}

そして、次の派生クラス:

[DataContract]
[Serializable]
public class ClearingSite : DimensionEntity
{
    [DataMember(Order = 1)]
    private readonly string code;
    ...
}

次のようにインスタンスをシリアル化するとClearingSite、次のようになります。

        model.Add(typeof(ClearingSite), true);
        model.Serialize(ms, clearingSite);

codeのメンバーのみClearingSiteがシリアル化されていることがわかります。基本クラスのeffectiveDatespanメンバーの値はシリアル化されません。

2つのメモ:

  1. BaseTypeaddのメンバーProtoBuf.Meta.MetaTypeがに設定されているためnulleffectiveDatespanメンバーがシリアル化されていないことがわかります。代わりに、モデルをコンパイルすると、そのBaseTypeメンバーは正しく設定されます(ただし、メンバーはコンパイルされたモデルからアクセスできないためDimensionEntity、後で失敗します)。private readonly
  2. もちろんClearingSite、既知のタイプとして宣言するDimensionEntityことはできますが、なぜこれが必要になるのかわかりません。シリアル化していないDimensionEntity、シリアル化(および逆シリアル化)しているClearingSite、さらにDataContractSerializer追加する必要がないKnownTypeDimensionEntityシリアル化する場合にClearingSite

Marcからの他の回答から、Protobufは「すべての重要なフィールド番号」(引用符)を取得するためにKnownType(または)属性を必要とするように見えますが、。がなくても完全に正常に機能ProtoIncludeするため、そうではないようです。CompiledModelProtoInclude

System.Runtime.Serializationオブジェクトモデルが将来的にシリアライザーを認識しないようにしようとしているので、属性のみを使用するように努めていることに注意してください。

4

1 に答える 1

2

ProtoIncludeまたは同等のものが絶対に必要です。コンパイルされたバージョンで何か奇妙なことが起こっている場合、それはバグであり、私は調査することができます。

タイプに非BCL属性を追加したくない場合は、実行時にこれを行うことができます。

RuntimeTypeModel.Default[typeof(BaseType)]
    .AddSubClass(.....);

(またはそのような何か-私はPCにいません)

于 2012-05-01T17:31:38.037 に答える