2011-06-30 19 views
7

私はReadOnlyCollectionを通じてコレクションを公開するコンテナクラスをいくつか持っています。カスタムメソッドは、カスタムロジックを実行するコレクションからの追加と削除に提供されます。例えばReadOnlyCollectionsのXmlシリアル化

public class Foo 
{ 
    List<Bar> _barList = new List<Bar>(); 

    public ReadOnlyCollection<Bar> BarList 
    { 
     get { return _barList.AsReadOnly(); } 
    } 

    public void AddBar(Bar bar) 
    { 
     if (bar.Value > 10) 
      _barList.Add(bar); 
     else 
      MessageBox.Show("Cannot add to Foo. The value of Bar is too high"); 
    } 
    public void RemoveBar(Bar bar) 
    { 
     _barList.Remove(bar); 
     // Foo.DoSomeOtherStuff(); 
    } 

} 

public class Bar 
{ 
    public string Name { get; set; } 
    public int Value { get; set; } 
} 

これはすべてが順調と良いですが、私は、XMLシリアライザではFooをシリアル化するために来たときに例外がスローされます。

誰でもこれについて良い方法を提供できますか?

おかげ

+0

例外は何ですか? –

+1

Fooを反映する際にエラーが発生したため、InvalidOperationExceptionがスローされます。 –

答えて

2

それはAddメソッドを持っていないので、あなたはReadOnlyCollectionをデシリアライズすることはできません。 は直列化のためにその使用をもう一度プロパティを修正するには:

[XmlIgnore()] 
public ReadOnlyCollection<Bar> BarList 
{ 
    get { return _barList.AsReadOnly(); } 
} 

[Browsable(false)] 
[EditorBrowsable(EditorBrowsableState.Never)] 
[DebuggerBrowsable(DebuggerBrowsableState.Never)] 
//[Obsolete("This is only for serialization process", true)] 
[XmlArray("BarList")] 
[XmlArrayItem("Bar")] 
public List<Bar> XmlBarList 
{ 
    get { return _barList; } 
    set { _barList = value; } 
} 
+2

私はObsoleteとしてマークされたプロパティは、同様にシリアル化されていないと思います... –

+1

@Frederik:ちょうどそれにテストを与え、あなたが正しいことを発見しました。 'Obsolete'プロパティは直列化されません。コメントをいただき、ありがとうございます。 –

+0

こんにちは、回答ありがとうございます。廃止タグを追加するとシリアライズを防ぐことができます –

4

確かに、それは動作しません。そうしないでください。さらに、あまりにも痛いIXmlSerializableを除いてxmlのシリアル化を検出するためのフックがありません。だから、

次のいずれか

  • は、ここでは読み取り専用のコレクションを使用していない
  • (トリッキー)IXmlSerializableを実装
  • は、1つの読み取り専用(1を二重のAPIを持っていない; "をシリアル化ではない」 - XmlSerializerなどトリッキーなだけpublicxメンバーを扱う)
  • シリアライズ