1

オブジェクトをシリアル化するために DataContracts を使用しています。次のように構造化されたデータをシリアル化したとします。

[DataContract]
public class Dog : IExtensibleDataObject
{
    [DataMember]
    public int age;

    [DataMember]
    public string name;

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
}

現在、アーキテクチャを変更しており、以前にシリアル化されたデータをこのクラスで読み取りたいと考えています。

[DataContract]
[KnownType(typeof(Dog))]
public class Animal : IExtensibleDataObject
{
    [DataMember]
    public string name;

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; }
}

[DataContract]
public class Dog : Animal
{
    [DataMember]
    public int age;
}

しかし、私は name = null を取得します。これは順序に依存することを知っています。ファイルは最初に年齢とともに保存され、次に名前から読み取られます。これは、基本クラスにあるためです。
おそらく順序を変更することによって、これを処理する方法はありますか?

4

2 に答える 2

3

それは不可能だと思います。

過去のxmlは

<dog>
    <name>Bob</name>
    <age>10</age>
</dog>

今期待している

<animal>
    <name>Bob</name>
    <dog>
        <age>10</age>
    </dog>
</animal>

このプロパティは、新しい DataContract でシリアル化されたものより上位にあります。継承階層の変更は、IExtensibleDataObjectメソッドの破壊的変更です。

継承がバージョン管理メカニズムとして使用されておらず、特定の規則が守られている場合は、継承をデータ コントラクトと共に使用することができます。ある型が特定の基本型から派生している場合は、将来のバージョンで別の基本型から派生させないでください (同じデータ コントラクトがある場合を除きます)。これには例外が 1 つあります。データ コントラクト型とその基本型の間の階層に型を挿入できます。階層。一般に、同じ継承階層の異なるレベルで同じ名前のデータ メンバーを使用すると、重大なバージョン管理の問題が発生する可能性があるため、避ける必要があります。

ベスト プラクティスの詳細: データ コントラクトのバージョン管理

編集1:

Animal で Name を virtual にして、Dog でオーバーライドしてみてはいかがでしょうか。または、シリアル化された新しいバージョンに犬の下の名前を強制するクレイジーな方法。つまり、次のようなものです。

[DataContract] 
[KnownType(typeof(Dog))] 
public class Animal : IExtensibleDataObject 
{
    public virtual string name; 

    ExtensionDataObject IExtensibleDataObject.ExtensionData { get; set; } 
} 

[DataContract] 
public class Dog : Animal 
{ 
    [DataMember] 
    public override string name; 

    [DataMember] 
    public int age; 
} 
于 2012-05-30T15:23:59.480 に答える
1

このSO投稿で説明されているWCFコントラクトのバージョン管理をご覧ください。

基本的に、コントラクトが進化するにつれて下位互換性が必要な場合は、を割り当てて、新しいバージョンと古いバージョンの両方を維持する必要がありNamespaceます。ServiceContract

于 2012-05-30T15:27:11.630 に答える