私は、各外側のレイヤーがその下のレイヤーの上に構築されているという点で、「タマネギのような」と最もよく説明されているデータを持っています。以下に、非常に単純化されたバージョンが表示されます (私のものは数層深くなりますが、各レベルで同じ動作を示します)。
[CollectionDataContract]
public abstract class AbstractTestGroup : ObservableCollection<AbstractTest>
{
[DataMember]
public abstract string Name { get; set; }
}
[CollectionDataContract]
[KnownType(typeof(Test))]
public class TestGroup : AbstractTestGroup
{
public override string Name
{
get { return "TestGroupName"; }
set { }
}
[DataMember]
public string Why { get { return "Why"; } set { } }
}
[DataContract]
public abstract class AbstractTest
{
[DataMember]
public abstract string SayHello { get; set; }
}
[DataContract]
public class Test : AbstractTest
{
//Concrete class - members in this class get serialized
[DataMember]
public string Month { get { return "June"; } set { } }
public override string SayHello { get { return "HELLO"; } set { } }
}
のインスタンスを作成し、付属の を使用してオブジェクトをTestGroup
追加します。Test
.Add
ObservableCollection
この構造をシリアライズおよびデシリアライズすると、次のようになります。
<TestGroup xmlns="http://schemas.datacontract.org/2004/07/WpfApplication2" xmlns:i="http://www.w3.org/2001/XMLSchema-instance">
<AbstractTest i:type="Test">
<SayHello>HELLO</SayHello>
<Month>June</Month>
</AbstractTest>
</TestGroup>
出力ではDataMember
s inが省略されていTestGroup
ます。タマネギを深く掘り下げると、DataMember
より高い s は含まれません (抽象クラスからでも)。[KnownType(typeof(TestGroup))]
私は両方に追加しようとしましたが、成功しませんでしたTestGroup
。AbstractTestGroup
質問:クラスDataMember
Why
でをシリアル化できないのはなぜですか?TestGroup
フォローアップの質問:この形状の構造をシリアライズおよびデシリアライズする別の方法はありますか? 出力をローカルで使用して、ユーザーが指定した構成を「ロード」することを計画しています。回避できるのであれば、独自のシリアル化スキームを指定する必要はありません。
興味のある方は、クラスの生成、シリアライズ、デシリアライズの方法について説明します。
TestGroup tg = new TestGroup();
tg.Add(new Test());
DataContractSerializer ser = new DataContractSerializer(typeof(TestGroup));
MemoryStream memoryStream = new MemoryStream();
ser.WriteObject(memoryStream, tg);
memoryStream.Seek(0, SeekOrigin.Begin);
string str;
using (StreamReader sr = new StreamReader(memoryStream))
str = sr.ReadToEnd();
編集:Serializable
代わりに使用するように変更してみましたが、同じ問題がありました。