BindingList から継承するカスタム タイプのコレクション プロパティがあります。現在、このプロパティは、Setter がなくても XmlSerializer を介してシリアル化されます。現在、このカスタム コレクション クラスに IXmlSerializable を実装しようとしており、コレクション プロパティに Setter がある場合にのみ、WriteXml() および ReadXml() インターフェイス メソッドが呼び出されることを確認しています。Setter がなくても正しくシリアル化される前に、Setter がない限り、シリアル化がこのプロパティを無視するのはなぜですか。
再現するには:
まず、「Item」というクラスを用意します。
public class Item
{
public Item() {}
// Generates some random data for the collection
private MyCollectionType GenerateContent()
{
Random ranGen = new Random();
MyCollectionType collection = new MyCollectionType();
for (int i = 0; i < 5; i ++)
{
collection.Add("Item" + ranGen.Next(0,101));
}
return collection;
}
public MyCollectionType Items
{
get
{
if (m_Items == null)
{
m_Items = GenerateContent();
}
return m_Items;
}
}
private MyCollectionType m_Items = null;
}
次に、コレクション クラス "MyCollectionType" を作成します (最初のスニペットでは IXmlSerializable が意図的に欠落していることに注意してください)。
public class MyCollectionType : BindingList<string>
{
public MyCollectionType()
{
this.ListChanged += MyCollectionType_ListChanged;
}
void MyCollectionType_ListChanged(object sender, ListChangedEventArgs e){ }
public MyCollectionType(ICollection<string> p)
{
this.ListChanged += MyCollectionType_ListChanged;
}
#region Implementation of IXmlSerializable
public void WriteXml(XmlWriter writer)
{
throw new NotImplementedException();
}
public void ReadXml(XmlReader reader)
{
throw new NotImplementedException();
}
public XmlSchema GetSchema() { return null; }
#endregion
}
最後に、「アイテム」をシリアライズおよびデシリアライズするコードを Main() に追加します。
Item myItem = new Item();
Item newItem = null;
// Define an XmlSerializer
XmlSerializer ser = new XmlSerializer(typeof(Item));
// Serialize the Object
using (TextWriter writer = File.CreateText(@"c:\temporary\exportedfromtest.xml"))
{
ser.Serialize(writer,myItem);
}
// Deserialize it
using (Stream reader = new FileStream(@"c:\temporary\exportedfromtest.xml", FileMode.Open, FileAccess.Read, FileShare.Read))
{
using (XmlDictionaryReader xmlDictionaryReader = XmlDictionaryReader.CreateTextReader(reader, XmlDictionaryReaderQuotas.Max))
{
newItem = (Item)ser.Deserialize(xmlDictionaryReader);
}
}
したがって、そのまま実行すると、Setter なしでシリアル化および逆シリアル化されることがわかります。現在、コレクションは上記のスニペットに「IXmlSerializable」をリストしていませんが、メソッドはそこにあります。したがって、戻って MyCollectionType クラスに "IXmlSerializable" を追加して再度実行すると、コレクション プロパティがシリアル化されておらず、WriteXml() メソッドと ReadXml() メソッドが呼び出されていないことがわかります。また、空の Setter を追加すると、これらのメソッドが突然呼び出されることに注意してください。