2011-01-10 5 views
1

共通のインターフェイスを実装するオブジェクトの一覧があります。
「それはインターフェースがあるので...タイプで...シリアライズできないメンバー」XmlSerializerエラーシリアルインターフェイスオブジェクト

private readonly ObservableCollection<ICanHasInterface> children = new ObservableCollection<ICanHasInterface>(); 
public ObservableCollection<ICanHasInterface> Children 
{ 
    get { return children; } 
} 

=>:私は単にそれをシリアル化しようとした場合、私は、シリアライザは、インタフェースをシリアル化することができないことを私に伝える素敵な例外を取得します
明らかに、シリアライザにオブジェクトの型を取得し、属性がxsi:type(オブジェクトが別のクラスを継承する場合に行われる)のXmlElementをマークすることを余儀なくされています。私はIXmlSerializableを実装したくないので
だから、私は当初有望に見えた回避策を思いついた:少なくともシリアル化だけで正常に動作これにより

private readonly ObservableCollection<ICanHasInterface> children = new ObservableCollection<ICanHasInterface>(); 
[XmlIgnore()] 
public ObservableCollection<ICanHasInterface> Children 
{ 
    get { return children; } 
} 

[XmlElement("Child")] 
public List<object> ChildrenSerialized 
{ 
    get 
    { 
     return new List<object>(Children); 
    } 
    set 
    { 
     Children.Clear(); 
     foreach (var child in value) 
     { 
      if (child is ICanHasInterface) AddChild(child as ICanHasInterface); 
     } 
    } 
} 

を(注:いずれかのことができタイプのためXmlInclude属性を指定します元のリストにあるか、シリアライザのコンストラクタに配列の配列を渡してください)。逆シリアル化中にsetブロックに到達しないため、オブジェクトが逆シリアル化された場合、Childrenコレクションは空になります。なぜこのそうです。何か案は?

答えて

1

シリアライザは、プロパティゲッターを使用してコレクションインスタンスを取得し、各インスタンスに対してAdd()を呼び出します。それはあなたの財産セッターを呼びません。このような何か:あなたはプロパティのゲッターから復帰コレクションのAdd()の挙動をカスタマイズする必要があると思い、同期のコレクションを維持するためには

YourClass c = new YourClass(); 
c.ChildrenSerialized.Add(ReadValue()); 
... 

より良いオプションは、オブジェクト[]を使用するようにChildrenSerializedプロパティを変更することです。配列の場合、シリアライザは値を配列に読み込んだ後、その値でプロパティセッターを呼び出します。

+0

ありがとうございます、配列を使って完全に動作します! –

関連する問題